+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- 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
-
- 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
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program 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, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU 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 Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+++ /dev/null
-
-VERSION = 0.1.1
-REVISION = 1
-
-SHELL := ${shell which bash}
-
-IPATH += src
-IPATH += srcgl
-VPATH += src
-VPATH += srcgl
-
-OBJ = obj-${shell $(CC) -dumpmachine}
-
-C3SRC = ${wildcard src/*.c}
-C3OBJ = ${patsubst src/%,${OBJ}/%,${C3SRC:.c=.lo}}
-
-C3GLSRC = ${wildcard srcgl/*.c}
-C3GLOBJ = ${patsubst srcgl/%,${OBJ}/%,${C3GLSRC:.c=.lo}}
-
-CC = clang
-PKGCONFIG = pkg-config
-INSTALL = install
-
-PLATFORM = ${shell uname | tr '[A-Z]' '[a-z]'}
-
-ifeq (${PLATFORM}, darwin)
-# you need to install libtool via 'brew install libtool' on the mac
-LIBTOOL = glibtool
-else
-LIBTOOL = libtool
-endif
-
-CONFIG_H = c3config-${PLATFORM}.h
-CPPCAIRO += ${shell $(PKGCONFIG) --cflags pango cairo}
-
-CFLAGS = -g -O2
-CPPFLAGS += --std=gnu99 -fPIC
-CPPFLAGS += ${patsubst %,-I%,${subst :, ,${IPATH}}}
-CPPFLAGS += $(CPPCAIRO)
-
-LDFLAGS +=
-
-DESTDIR = /usr/local
-
--include ${wildcard .make.options*}
-
-all: ${OBJ} src/$(CONFIG_H) ${OBJ}/libc3.la ${OBJ}/libc3gl.la
-
-${OBJ}:
- mkdir -p ${OBJ}
-
-ifneq (${V}, 1)
-E=@
-LIBTOOL += --quiet
-endif
-
-src/$(CONFIG_H): Makefile
- $(E)rm -f $@
- $(E)echo CONFIG $@
- $(E)( \
- printf "#ifndef __C3_CONFIG__\n#define __C3_CONFIG__\n"; \
- printf "#define CONFIG_C3_VERSION \"$(VERSION)\"\n"; \
- printf "#define CONFIG_C3_PLATFORM \"$(PLATFORM)\"\n"; \
- $(PKGCONFIG) --exists pango cairo || printf "// " ; \
- printf "#define CONFIG_C3_CAIRO 1\n"; \
- printf "#endif\n"; \
- ) >$@
-
-${OBJ}/libc3.la: ${C3OBJ}
- @echo LINK $@
- $(E)$(LIBTOOL) --mode=link --tag=CC \
- $(CC) $(CPPFLAGS) $(CFLAGS) \
- $^ -o $@ \
- -version-info 0:1:0 \
- -rpath $(DESTDIR)/lib $(LDFLAGS)
-
-${OBJ}/libc3gl.la: ${C3GLOBJ}
- @echo LINK $@
- $(E)$(LIBTOOL) --mode=link --tag=CC \
- $(CC) $(CPPFLAGS) $(CFLAGS) \
- $^ -o $@ \
- -version-info 0:1:0 \
- -rpath $(DESTDIR)/lib $(LDFLAGS)
-
-${OBJ}/%.lo: %.c
- @echo CC $<
- $(E)$(LIBTOOL) --mode=compile --tag=CC \
- $(CC) $(CPPFLAGS) $(CFLAGS) -MT $@ -MMD \
- $< -c -o $@
-
-install:
- mkdir -p $(DESTDIR)/lib/pkgconfig $(DESTDIR)/include/c3
- rm -f $(DESTDIR)/lib/libc3* $(DESTDIR)/include/c3/*
- $(INSTALL) src/*.h $(DESTDIR)/include/c3/
- cp -a ${OBJ}/.libs/*.a ${OBJ}/.libs/*.so* $(DESTDIR)/lib/
- sed -e 's|PREFIX|${DESTDIR}|g' -e 's|VERSION|${VERSION}|g' \
- libc3.pc >$(DESTDIR)/lib/pkgconfig/libc3.pc
-
-clean:
- rm -rf ${OBJ}
-
-# include the dependency files generated by gcc, if any
--include ${wildcard ${OBJ}/*.d}
-
\ No newline at end of file
+++ /dev/null
-**libc3** - No frill 'scene' graph library in C
-=====
-(C) 2012 Michel Pollet <buserror@gmail.com>
-
-**WARNING** This API is not your nanny. It is made to be lean, mean, efficient
-with no frill, no asserts, no bounds checking, no sugar coating.
-
-On the other hand it's fast, reasonably clean and is a micro-fraction of the
-other giganormous 'scene graphs' or 'game engine' libraries around.
-
-It's vaguely inspired by THREE.js funnily enough, because it allows you to
-hack around and quickly get stuff on screen with the minimal amount of
-effort.
-
-Introduction
------------
-The general idea is that the library keeps track of geometry and stuff, but doesn't
-do *any* opengl or related calls. Instead, it uses callbacks into code that will
-take care of the rendering related tasks.
-
-So for example a c3pixels represents a texture, but a callback into the rendering
-layer will be responsible to push the pixels to OpenGL, and store the object back
-into the c3pixels for reference.
-
-Status
--------
-The API is generally functional, but it's brand new. I try not to add bits that
-I aren't needed, and I also don't add stuff that isn't tested.
-
-There is an ASCII STL file loader that works, and a few other bit of geometry related
-helpers.
-
-It's currently used in one 'serious' project and also in my [3D printer simulator](https://github.com/buserror-uk/simavr/tree/master/examples/board_reprap),
-as part of simavr. There you cal also find the "opengl renderer" set of callbacks, in the
-near future, this layer will be part of a *libc3-gl* companion library.
-
-General Roadmap
----------------
-There is a [PDF Flowchart](https://github.com/buserror-uk/libc3/raw/master/doc/libc3-flowchart.pdf)
-of how things are mostly organized as far as data structure goes, but the following is a
-breakdown of the major components.
-
-The API has various bits:
-* c3algebra: C derivative of an old C++ piece of code I had lying around and that has
-been present in my toolset for a long time. It gives you *vectors* (c3vec2, c3vec3, c3vec4)
-and *matrices* (c3mat3, c3mat4) with various tools to manipulate them.
-* c3quaternion: Quaternion implementation using c3algebra
-* c3camera/c3arcball: camera manipulation bits
-
-The basic data structure is as follow:
-* *c3context*:
- Hosts a "root" object, and a list of 'viewpoints' (ie either cameras, or lights).
- it can reproject the objects & geometries, and call the callbacks to draw them.
-
- The context also keeps a list of *c3pixels* and *c3program* that are referenced
- by the geometries.
-* *c3object*:
- * Has a list of (sub) c3objects
- * Has a list of c3transforms (ie matrices)
- * Has a list of c3geometry (ie real vertices and stuff)
- The object is a container for other objects, and for geometry itself. Objects don't
- necessary have geometry and/or sub objects, and don't even need transforms if their
- vertices are already projected.
-* *c3geometry*:
- * Has a 'type' (raw for simple vertices, texture, triangles etc)
- * Has a 'subtype' (mostly can be used to draw GL types)
- * Has a 'material' (ie color, texture, a GPU program... to be completed)
- * Has a list of vertices
- * Has a cached copy of a vertices when it has been 'projected'
- * Has a list of texture coordinates (optional)
- * Has a list of vertices colors (optional)
- * Had a list of vertices indexes (optional)
-* *c3transform*:
- Is just a sugar coated matrix, with an optional name.
-
-Also there are:
-* *c3pixels*:
- Is just a wrapper/holder for some pixels, either allocated, or inherited,
- it's mostly used for *c3texture*
-* *c3texture*:
- Associates a *c3geometry* with a *c3pixels* and has a standard Quad
- for vertices. The OpenGL drawing is not done there, it's done by the application using
- the generic *c3context* driver.
-* *c3cairo*:
- Placeholder for now, inherits from *c3texture* and will contain a
- cairo surface mapped to a GL texture.
-
-Draw Drivers "Inheritance"
-------------
-Various object uses static tables of callbacks to implement their behaviours
-it's kinda cheap c++ inheritance, without the usual bloat.
-
-There just a couple macros to call the driver chain for a particular function call.
-The relevant bits are in c3driver*.h.
-
-Mostly the code looks for a matching callback in a static table, and call it if found.
-If that callback wants, it can also call the inherited object callback too.
-
-Dirtyness
----------
-There is a notion of 'dirtyness' in the tree, when you touch a *c3transform*, and/remove
-objects and geometry, a dirty bit is propagated up the tree of object. This tells the
-rendering it needs to reproject the dirty bits and repopulate the projected vertice
-cache.
-
-The 'dirty' bit moves both ways, when setting a dirty bit to true, it propagates upward,
-when you set it to false, it propagates downward in the tree.
+++ /dev/null
-digraph g {
-// label = "libc3\n - lightweight scene graph library - Data Structure Hierarchy";
- label = <
- <font point-size="18">libc3</font> -
- <font color="blue">http://github.com/buserror-uk/libc3</font>
- - Lightweight C Scene Graph Library - Data Structure Flowchart
- >;
- node [fontsize=24,shape=box];
- // concentrate=true;
-
- c3context [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3context</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Keeps track of a root c3object,<br/>
- possible multiple views, and also stores <br/>
- texture pixels and shader programs
- </font></td></tr>
- </table>
- >];
- c3context_view [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3context_view</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Keep tracks of a scene point of view.<br/>
- used for the eye(s), and the light(s)
- </font></td></tr>
- </table>
- >];
- c3camera [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3camera</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Keeps an 'eye' point, a 'lookat'<br/>
- point the related vectors, and a<br/>
- transform matrix
- </font></td></tr>
- </table>
- >];
- c3object [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3object</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Anchor point that holds optional<br/>
- transform matrices, other sub-c3objects<br/>
- and c3geometries<br/>
- </font></td></tr>
- </table>
- >];
- c3transform [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3transform</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Holds a matrix to be applies to<br/>
- a c3object and it's descendants
- </font></td></tr>
- </table>
- >];
- c3cairo [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4" color="gray">
- <tr><td>c3cairo</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Maps a Cairo image surface<br/>
- to a c3texture - Optional.
- </font></td></tr>
- </table>
- >];
- c3texture [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3texture</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Provides a geometry to render a<br/>
- c3pixel (and anonymous texture)
- </font></td></tr>
- </table>
- >];
- c3geometry [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3geometry</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Contains the real drawing data, vertices,<br/>
- tex coordinates, normals and a material.
- </font></td></tr>
- </table>
- >];
- c3pixels [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3pixels</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Basic description of a pixmap<br/>
- to be loaded as a texture.
- </font></td></tr>
- </table>
- >];
- c3program [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3program</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Holds a vertex/fragment/... program,<br/>
- also parses them for uniform/parameters
- </font></td></tr>
- </table>
- >];
- c3color [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3color</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Base RGBA float color
- </font></td></tr>
- </table>
- >];
- c3vertex [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3vertex</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Array of X,Y,Z coordinates,<br/>
- with associated buffer object
- </font></td></tr>
- </table>
- >];
- c3normal [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3normal</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Array of normals with<br/>
- associated buffer object
- </font></td></tr>
- </table>
- >];
- c3tex [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3tex</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Array of texture coordinates<br/>
- with associated buffer object
- </font></td></tr>
- </table>
- >];
- c3indice [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3indice</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Array of indices into<br/>
- the other arrays
- </font></td></tr>
- </table>
- >];
- c3mat [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3mat</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Geometry material related data<br/>
- ie color, texture, program.
- </font></td></tr>
- </table>
- >];
- c3stl [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3stl</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Loads ASCII STL model files<br/>
- and generates corresponding c3object.
- </font></td></tr>
- </table>
- >];
- c3lines [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3lines</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Converts segments into a textured<br/>
- triangle mesh for wide, <br/>
- antialiasied lines
- </font></td></tr>
- </table>
- >];
- c3sphere [shape=none, label=<
- <table border="1" cellborder="0" cellpadding="4">
- <tr><td>c3sphere</td></tr>
- <tr><td color="gray" border="1" align="center"><font point-size="10">
- Creares geometry for a sphere<br/>
- with texture coordinaes&normals
- </font></td></tr>
- </table>
- >];
- c3context -> c3context_view;
- c3context -> c3object [style=bold];
- c3context -> c3pixels [style=dashed];
- c3context -> c3program [style=dashed];
-
- c3context_view -> c3camera;
-
- { rank = same; c3object; c3stl; }
- { rank = same; c3geometry; c3lines; c3sphere; }
- c3stl -> c3object [ weight=0.1, color="gray" ];
- c3lines -> c3geometry [ weight=0.1, color="gray" ];
- c3sphere -> c3geometry [ weight=0.1, color="gray" ];
-
- c3texture -> c3geometry;
- { node [style=dashed]; c3cairo; }
- c3cairo -> c3texture;
-
- c3object -> c3geometry [style=bold];
- c3object -> c3texture;
- c3object -> c3cairo;
- c3object -> c3transform;
-
- c3object -> c3object;
-
- c3geometry -> c3vertex;
- c3geometry -> c3normal ;
- c3geometry -> c3tex;
- c3geometry -> c3mat;
- c3geometry -> c3indice;
-
- c3mat -> c3pixels;
- c3mat -> c3program;
- c3mat -> c3color;
-
- c3texture -> c3pixels;
-};
+++ /dev/null
-libc3.pc:
-prefix=PREFIX
-exec_prefix=${prefix}
-includedir=${prefix}/include
-libdir=${exec_prefix}/lib
-
-Name: libc3
-Description: Lightweight scene graph library in C
-Version: VERSION
-Cflags: -I${includedir}
-Requires.private: pangocairo
-Libs: -L${libdir} -llibc3
+++ /dev/null
-/*
- c3.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3.h"
-#include "c3config.h"
-
-const char *
-c3version()
-{
- return CONFIG_C3_VERSION;
-}
+++ /dev/null
-/*
- c3.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3_H___
-#define __C3_H___
-
-#include "c3context.h"
-#include "c3object.h"
-#include "c3geometry.h"
-#include "c3transform.h"
-#include "c3texture.h"
-
-const char *
-c3version();
-
-#endif /* __C3_H___ */
+++ /dev/null
-/*
- c3algebra.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- Derivative and inspiration from original C++:
- Paul Rademacher & Jean-Francois DOUEG,
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include <string.h>
-#include "c3algebra.h"
-
-#ifndef MAX
-#define MAX(a,b) ((a)>(b) ? (a) : (b))
-#define MIN(a,b) ((a)<(b) ? (a) : (b))
-#endif
-
-/****************************************************************
- * *
- * c3vec2 Member functions *
- * *
- ****************************************************************/
-
-/******************** c3vec2 CONSTRUCTORS ********************/
-
-c3vec2 c3vec2_zero()
-{
- c3vec2 n;// = { .x = 0, .y = 0 };// older gcc <4.6 doesn't like this
- n.x = n.y = 0;
- return n;
-}
-
-c3vec2 c3vec2f(c3f x, c3f y)
-{
- c3vec2 v;// = { .x = x, .y = y };// older gcc <4.6 doesn't like this
- v.x = x; v.y = y;
- return v;
-}
-
-/******************** c3vec2 ASSIGNMENT OPERATORS ******************/
-
-c3vec2 c3vec2_add(c3vec2 a, const c3vec2 v)
-{
- a.n[VX] += v.n[VX];
- a.n[VY] += v.n[VY];
- return a;
-}
-
-c3vec2 c3vec2_sub(c3vec2 a, const c3vec2 v)
-{
- a.n[VX] -= v.n[VX];
- a.n[VY] -= v.n[VY];
- return a;
-}
-
-c3vec2 c3vec2_mulf(c3vec2 a, c3f d)
-{
- a.n[VX] *= d;
- a.n[VY] *= d;
- return a;
-}
-
-c3vec2 c3vec2_divf(c3vec2 a, c3f d)
-{
- c3f d_inv = 1.0f/d;
- a.n[VX] *= d_inv;
- a.n[VY] *= d_inv;
- return a;
-}
-
-/******************** c3vec2 SPECIAL FUNCTIONS ********************/
-
-
-c3f c3vec2_length2(const c3vec2 a)
-{
- return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY];
-}
-
-c3f c3vec2_length(const c3vec2 a)
-{
- return (c3f) sqrt(c3vec2_length2(a));
-}
-
-c3vec2 c3vec2_normalize(const c3vec2 a) // it is up to caller to avoid divide-by-zero
-{
- return c3vec2_divf(a, c3vec2_length(a));
-}
-
-c3vec2 c3vec2_apply(c3vec2 a, V_FCT_PTR fct)
-{
- a.n[VX] = fct(a.n[VX]);
- a.n[VY] = fct(a.n[VY]);
- return a;
-}
-
-
-/******************** c3vec2 FRIENDS *****************************/
-
-c3vec2 c3vec2_minus(const c3vec2 a)
-{
- return c3vec2f(-a.n[VX],-a.n[VY]);
-}
-
-c3vec2 c3mat3_mulv2(const c3mat3p a, const c3vec2 v)
-{
- c3vec2 av;
-
- av.n[VX] = a->v[0].n[VX]*v.n[VX] + a->v[0].n[VY]*v.n[VY] + a->v[0].n[VZ];
- av.n[VY] = a->v[1].n[VX]*v.n[VX] + a->v[1].n[VY]*v.n[VY] + a->v[1].n[VZ];
-// av.n[VZ] = a.v[2].n[VX]*v.n[VX] + a.v[2].n[VY]*v.n[VY] + a.v[2].n[VZ];
-
- return av;
-}
-
-c3vec2 c3vec2_mulm3(const c3vec2 v, const c3mat3p a)
-{
- c3mat3 t = c3mat3_transpose(a);
- return c3mat3_mulv2(&t, v);
-}
-
-c3vec3 c3mat3_mulv3(const c3mat3p a, const c3vec3 v)
-{
- c3vec3 av;
-
- av.n[VX] = a->v[0].n[VX]*v.n[VX] + a->v[0].n[VY]*v.n[VY] + a->v[0].n[VZ]*v.n[VZ];
- av.n[VY] = a->v[1].n[VX]*v.n[VX] + a->v[1].n[VY]*v.n[VY] + a->v[1].n[VZ]*v.n[VZ];
- av.n[VZ] = a->v[2].n[VX]*v.n[VX] + a->v[2].n[VY]*v.n[VY] + a->v[2].n[VZ]*v.n[VZ];
-
- return av;
-}
-
-c3vec3 c3vec3_mulm3(const c3vec3 v, const c3mat3p a)
-{
- c3mat3 t = c3mat3_transpose(a);
- return c3mat3_mulv3(&t, v);
-}
-
-c3f c3vec2_dot(const c3vec2 a, const c3vec2 b)
-{
- return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY];
-}
-
-c3vec3 c3vec2_cross(const c3vec2 a, const c3vec2 b)
-{
- return c3vec3f(0.0, 0.0, a.n[VX] * b.n[VY] - b.n[VX] * a.n[VY]);
-}
-
-int c3vec2_equal(const c3vec2 a, const c3vec2 b)
-{
- return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]);
-}
-
-
-c3vec2 c3vec2_min(const c3vec2 a, const c3vec2 b)
-{
- return c3vec2f(MIN(a.n[VX], b.n[VX]), MIN(a.n[VY], b.n[VY]));
-}
-
-c3vec2 c3vec2_max(const c3vec2 a, const c3vec2 b)
-{
- return c3vec2f(MAX(a.n[VX], b.n[VX]), MAX(a.n[VY], b.n[VY]));
-}
-
-c3vec2 c3vec2_prod(const c3vec2 a, const c3vec2 b)
-{
- return c3vec2f(a.n[VX] * b.n[VX], a.n[VY] * b.n[VY]);
-}
-
-/****************************************************************
- * *
- * c3vec3 Member functions *
- * *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-c3vec3 c3vec3_zero()
-{
- c3vec3 n;// = { .x = 0, .y = 0, .z = 0 };// older gcc <4.6 doesn't like this
- n.x = n.y = n.z = 0;
- return n;
-}
-
-c3vec3 c3vec3f(c3f x, c3f y, c3f z)
-{
- c3vec3 v;// = { .x = x, .y = y, .z = z };// older gcc <4.6 doesn't like this
- v.x = x; v.y = y; v.z = z;
- return v;
-}
-
-c3vec3 c3vec3_vec2f(const c3vec2 v, c3f d)
-{
- c3vec3 n;// = { .x = v.x, .y = v.y, .z = d }; // older gcc <4.6 doesn't like this
- n.x = v.x; n.y = v.y; n.z = d;
- return n;
-}
-
-c3vec3 c3vec3_vec2(const c3vec2 v)
-{
- return c3vec3_vec2f(v, 1.0);
-}
-
-c3vec3 c3vec3_vec4(const c3vec4 v) // it is up to caller to avoid divide-by-zero
-{
- c3vec3 n;
- n.n[VX] = v.n[VX] / v.n[VW];
- n.n[VY] = v.n[VY] / v.n[VW];
- n.n[VZ] = v.n[VZ] / v.n[VW];
- return n;
-}
-
-
-c3vec3 c3vec3_add(c3vec3 a, const c3vec3 v)
-{
- a.n[VX] += v.n[VX];
- a.n[VY] += v.n[VY];
- a.n[VZ] += v.n[VZ];
- return a;
-}
-
-c3vec3 c3vec3_sub(c3vec3 a, const c3vec3 v)
-{
- a.n[VX] -= v.n[VX];
- a.n[VY] -= v.n[VY];
- a.n[VZ] -= v.n[VZ];
- return a;
-}
-
-c3vec3 c3vec3_mulf(c3vec3 a, c3f d)
-{
- a.n[VX] *= d;
- a.n[VY] *= d;
- a.n[VZ] *= d;
- return a;
-}
-
-c3vec3 c3vec3_divf(c3vec3 a, c3f d)
-{
- c3f d_inv = 1.0f/d;
- a.n[VX] *= d_inv;
- a.n[VY] *= d_inv;
- a.n[VZ] *= d_inv;
- return a;
-}
-
-// SPECIAL FUNCTIONS
-
-c3f c3vec3_length2(const c3vec3 a)
-{
- return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY] + a.n[VZ]*a.n[VZ];
-}
-
-c3f c3vec3_length(const c3vec3 a)
-{
- return (c3f) sqrt(c3vec3_length2(a));
-}
-
-c3vec3 c3vec3_normalize(const c3vec3 a) // it is up to caller to avoid divide-by-zero
-{
- return c3vec3_divf(a, c3vec3_length(a));
-}
-
-c3vec3 c3vec3_homogenize(c3vec3 a) // it is up to caller to avoid divide-by-zero
-{
- a.n[VX] /= a.n[VZ];
- a.n[VY] /= a.n[VZ];
- a.n[VZ] = 1.0;
- return a;
-}
-
-c3vec3 c3vec3_apply(c3vec3 a, V_FCT_PTR fct)
-{
- a.n[VX] = fct(a.n[VX]);
- a.n[VY] = fct(a.n[VY]);
- a.n[VZ] = fct(a.n[VZ]);
- return a;
-}
-
-// FRIENDS
-
-c3vec3 c3vec3_minus(const c3vec3 a)
-{
- return c3vec3f(-a.n[VX],-a.n[VY],-a.n[VZ]);
-}
-
-#if later
-c3vec3 operator*(const c3mat4 &a, const c3vec3 &v)
-{
- return a*c3vec4(v);
-}
-
-c3vec3 operator*(const c3vec3 &v, c3mat4 &a)
-{
- return a.transpose()*v;
-}
-#endif
-
-c3f c3vec3_dot(const c3vec3 a, const c3vec3 b)
-{
- return a.n[VX]*b.n[VX] + a.n[VY]*b.n[VY] + a.n[VZ]*b.n[VZ];
-}
-
-c3vec3 c3vec3_cross(const c3vec3 a, const c3vec3 b)
-{
- return
- c3vec3f(a.n[VY]*b.n[VZ] - a.n[VZ]*b.n[VY],
- a.n[VZ]*b.n[VX] - a.n[VX]*b.n[VZ],
- a.n[VX]*b.n[VY] - a.n[VY]*b.n[VX]);
-}
-
-int c3vec3_equal(const c3vec3 a, const c3vec3 b)
-{
- return (a.n[VX] == b.n[VX]) && (a.n[VY] == b.n[VY]) && (a.n[VZ] == b.n[VZ]);
-}
-
-
-c3vec3 c3vec3_min(const c3vec3 a, const c3vec3 b)
-{
- return c3vec3f(
- MIN(a.n[VX], b.n[VX]),
- MIN(a.n[VY], b.n[VY]),
- MIN(a.n[VZ], b.n[VZ]));
-}
-
-c3vec3 c3vec3_max(const c3vec3 a, const c3vec3 b)
-{
- return c3vec3f(
- MAX(a.n[VX], b.n[VX]),
- MAX(a.n[VY], b.n[VY]),
- MAX(a.n[VZ], b.n[VZ]));
-}
-
-c3vec3 c3vec3_prod(const c3vec3 a, const c3vec3 b)
-{
- return c3vec3f(a.n[VX]*b.n[VX], a.n[VY]*b.n[VY], a.n[VZ]*b.n[VZ]);
-}
-
-c3vec3 c3vec3_polar(const c3vec3 a)
-{
- c3f l = c3vec3_length(a);
- c3f phi = atan2(a.y, a.x);
- c3f theta = acos(a.z / l);
- return c3vec3f(phi, theta, l);
-}
-
-/****************************************************************
- * *
- * c3vec4 Member functions *
- * *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-c3vec4 c3vec4_zero()
-{
- c3vec4 n ;//= { .x = 0, .y = 0, .z = 0, .w = 1.0 }; // older gcc <4.6 doesn't like this
- n.x = n.y = n.z = 0; n.w = 1.0;
- return n;
-}
-
-c3vec4 c3vec4f(c3f x, c3f y, c3f z, c3f w)
-{
- c3vec4 n;// = { .x = x, .y = y, .z = z, .w = w }; // older gcc <4.6 doesn't like this
- n.x =x; n.y = y; n.z = z; n.w = w;
- return n;
-}
-
-c3vec4 c3vec4_vec3(const c3vec3 v)
-{
- return c3vec4f(v.n[VX], v.n[VY], v.n[VZ], 1.0);
-}
-
-c3vec4 c3vec4_vec3f(const c3vec3 v, c3f d)
-{
- return c3vec4f(v.n[VX], v.n[VY], v.n[VZ], d);
-}
-
-// ASSIGNMENT OPERATORS
-
-c3vec4 c3vec4_add(c3vec4 a, const c3vec4 v)
-{
- a.n[VX] += v.n[VX];
- a.n[VY] += v.n[VY];
- a.n[VZ] += v.n[VZ];
- a.n[VW] += v.n[VW];
- return a;
-}
-
-c3vec4 c3vec4_sub(c3vec4 a, const c3vec4 v)
-{
- a.n[VX] -= v.n[VX];
- a.n[VY] -= v.n[VY];
- a.n[VZ] -= v.n[VZ];
- a.n[VW] -= v.n[VW];
- return a;
-}
-
-c3vec4 c3vec4_mulf(c3vec4 a, c3f d)
-{
- a.n[VX] *= d;
- a.n[VY] *= d;
- a.n[VZ] *= d;
- a.n[VW] *= d;
- return a;
-}
-
-c3vec4 c3vec4_divf(c3vec4 a, c3f d)
-{
- c3f d_inv = 1.0f/d;
- a.n[VX] *= d_inv;
- a.n[VY] *= d_inv;
- a.n[VZ] *= d_inv;
- a.n[VW] *= d_inv;
- return a;
-}
-
-// SPECIAL FUNCTIONS
-
-c3f c3vec4_length2(const c3vec4 a)
-{
- return a.n[VX]*a.n[VX] + a.n[VY]*a.n[VY] + a.n[VZ]*a.n[VZ] + a.n[VW]*a.n[VW];
-}
-
-c3f c3vec4_length(const c3vec4 a)
-{
- return (c3f) sqrt(c3vec4_length2(a));
-}
-
-c3vec4 c3vec4_normalize(c3vec4 a) // it is up to caller to avoid divide-by-zero
-{
- return c3vec4_divf(a, c3vec4_length(a));
-}
-
-c3vec4 c3vec4_homogenize(c3vec4 a) // it is up to caller to avoid divide-by-zero
-{
- a.n[VX] /= a.n[VW];
- a.n[VY] /= a.n[VW];
- a.n[VZ] /= a.n[VW];
- a.n[VW] = 1.0;
- return a;
-}
-
-c3vec4 c3vec4_apply(c3vec4 a, V_FCT_PTR fct)
-{
- a.n[VX] = fct(a.n[VX]);
- a.n[VY] = fct(a.n[VY]);
- a.n[VZ] = fct(a.n[VZ]);
- a.n[VW] = fct(a.n[VW]);
- return a;
-}
-
-c3vec4 c3mat4_mulv4(const c3mat4p a, const c3vec4 v)
-{
- #define ROWCOL(i) \
- a->v[i].n[0]*v.n[VX] + \
- a->v[i].n[1]*v.n[VY] + \
- a->v[i].n[2]*v.n[VZ] + \
- a->v[i].n[3]*v.n[VW]
-
- return c3vec4f(ROWCOL(0), ROWCOL(1), ROWCOL(2), ROWCOL(3));
-
- #undef ROWCOL
-}
-
-c3vec4 c3vec4_mulm4(const c3vec4 v, const c3mat4p a)
-{
- c3mat4 m = c3mat4_transpose(a);
- return c3mat4_mulv4(&m, v);
-}
-
-c3vec3 c3mat4_mulv3(const c3mat4p a, const c3vec3 v)
-{
- return c3vec3_vec4(c3mat4_mulv4(a, c3vec4_vec3(v)));
-}
-
-c3vec4 c3vec4_minus(const c3vec4 a)
-{
- return c3vec4f(-a.n[VX],-a.n[VY],-a.n[VZ],-a.n[VW]);
-}
-
-int c3vec4_equal(const c3vec4 a, const c3vec4 b)
-{
- return
- (a.n[VX] == b.n[VX]) &&
- (a.n[VY] == b.n[VY]) &&
- (a.n[VZ] == b.n[VZ]) &&
- (a.n[VW] == b.n[VW]);
-}
-
-c3vec4 c3vec4_min(const c3vec4 a, const c3vec4 b)
-{
- return c3vec4f(
- MIN(a.n[VX], b.n[VX]),
- MIN(a.n[VY], b.n[VY]),
- MIN(a.n[VZ], b.n[VZ]),
- MIN(a.n[VW], b.n[VW]));
-}
-
-c3vec4 c3vec4_max(const c3vec4 a, const c3vec4 b)
-{
- return c3vec4f(
- MAX(a.n[VX], b.n[VX]),
- MAX(a.n[VY], b.n[VY]),
- MAX(a.n[VZ], b.n[VZ]),
- MAX(a.n[VW], b.n[VW]));
-}
-
-c3vec4 c3vec4_prod(const c3vec4 a, const c3vec4 b)
-{
- return c3vec4f(
- a.n[VX] * b.n[VX],
- a.n[VY] * b.n[VY],
- a.n[VZ] * b.n[VZ],
- a.n[VW] * b.n[VW]);
-}
-
-/****************************************************************
- * *
- * c3mat3 member functions *
- * *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-c3mat3 c3mat3_identity()
-{
- return identity2D();
-}
-
-c3mat3 c3mat3_vec3(const c3vec3 v0, const c3vec3 v1, const c3vec3 v2)
-{
- c3mat3 m = { .v[0] = v0, .v[1] = v1, .v[2] = v2 };
- return m;
-}
-
-c3mat3p c3mat3_add(const c3mat3p a, const c3mat3p m)
-{
- a->v[0] = c3vec3_add(a->v[0], m->v[0]);
- a->v[1] = c3vec3_add(a->v[1], m->v[1]);
- a->v[2] = c3vec3_add(a->v[2], m->v[2]);
- return a;
-}
-
-c3mat3p c3mat3_sub(const c3mat3p a, const c3mat3p m)
-{
- a->v[0] = c3vec3_sub(a->v[0], m->v[0]);
- a->v[1] = c3vec3_sub(a->v[1], m->v[1]);
- a->v[2] = c3vec3_sub(a->v[2], m->v[2]);
- return a;
-}
-
-c3mat3p c3mat3_mulf(const c3mat3p a, c3f d)
-{
- a->v[0] = c3vec3_mulf(a->v[0], d);
- a->v[1] = c3vec3_mulf(a->v[1], d);
- a->v[2] = c3vec3_mulf(a->v[2], d);
- return a;
-}
-
-c3mat3p c3mat3_divf(const c3mat3p a, c3f d)
-{
- a->v[0] = c3vec3_divf(a->v[0], d);
- a->v[1] = c3vec3_divf(a->v[1], d);
- a->v[2] = c3vec3_divf(a->v[2], d);
- return a;
-}
-
-// SPECIAL FUNCTIONS
-
-c3mat3 c3mat3_transpose(const c3mat3p a)
-{
- return c3mat3_vec3(
- c3vec3f(a->v[0].n[0], a->v[1].n[0], a->v[2].n[0]),
- c3vec3f(a->v[0].n[1], a->v[1].n[1], a->v[2].n[1]),
- c3vec3f(a->v[0].n[2], a->v[1].n[2], a->v[2].n[2]));
-}
-
-c3mat3 c3mat3_inverse(const c3mat3p m) // Gauss-Jordan elimination with partial pivoting
-{
- c3mat3 a = *m; // As a evolves from original mat into identity
- c3mat3 b = c3mat3_identity(); // b evolves from identity into inverse(a)
- int i, j, i1;
-
- // Loop over cols of a from left to right, eliminating above and below diag
- for (j = 0; j < 3; j++) { // Find largest pivot in column j among rows j..2
- i1 = j; // Row with largest pivot candidate
- for (i = j + 1; i < 3; i++)
- if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
- i1 = i;
-
- // Swap rows i1 and j in a and b to put pivot on diagonal
- c3vec3 _s;
- _s = a.v[i1]; a.v[i1] = a.v[j]; a.v[j] = _s; // swap(a.v[i1], a.v[j]);
- _s = b.v[i1]; b.v[i1] = b.v[j]; b.v[j] = _s; //swap(b.v[i1], b.v[j]);
-
- // Scale row j to have a unit diagonal
- if (a.v[j].n[j] == 0.) {
- // VEC_ERROR("c3mat3::inverse: singular matrix; can't invert\n");
- return *m;
- }
-
- b.v[j] = c3vec3_divf(b.v[j], a.v[j].n[j]);
- a.v[j] = c3vec3_divf(a.v[j], a.v[j].n[j]);
-
- // Eliminate off-diagonal elems in col j of a, doing identical ops to b
- for (i = 0; i < 3; i++)
- if (i != j) {
- b.v[i] = c3vec3_sub(b.v[i], c3vec3_mulf(b.v[j], a.v[i].n[j]));
- a.v[i] = c3vec3_sub(a.v[i], c3vec3_mulf(a.v[j], a.v[i].n[j]));
- }
- }
-
- return b;
-}
-
-c3mat3p c3mat3_apply(c3mat3p a, V_FCT_PTR fct)
-{
- a->v[0] = c3vec3_apply(a->v[0], fct);
- a->v[1] = c3vec3_apply(a->v[1], fct);
- a->v[2] = c3vec3_apply(a->v[2], fct);
- return a;
-}
-
-
-c3mat3 c3mat3_minus(const c3mat3p a)
-{
- return c3mat3_vec3(
- c3vec3_minus(a->v[0]),
- c3vec3_minus(a->v[1]),
- c3vec3_minus(a->v[2]));
-}
-
-c3mat3 c3mat3_mul(const c3mat3p a, const c3mat3p b)
-{
- #define ROWCOL(i, j) \
- a->v[i].n[0]*b->v[0].n[j] + a->v[i].n[1]*b->v[1].n[j] + a->v[i].n[2]*b->v[2].n[j]
-
- return c3mat3_vec3(
- c3vec3f(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2)),
- c3vec3f(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2)),
- c3vec3f(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2)));
-
- #undef ROWCOL
-}
-
-int c3mat3_equal(const c3mat3p a, const c3mat3p b)
-{
- return
- c3vec3_equal(a->v[0], b->v[0]) &&
- c3vec3_equal(a->v[1], b->v[1]) &&
- c3vec3_equal(a->v[2], b->v[2]);
-}
-
-/****************************************************************
- * *
- * c3mat4 member functions *
- * *
- ****************************************************************/
-
-// CONSTRUCTORS
-
-c3mat4 c3mat4_identity()
-{
- return identity3D();
-}
-
-c3mat4 c3mat4_vec4(const c3vec4 v0, const c3vec4 v1, const c3vec4 v2, const c3vec4 v3)
-{
- c3mat4 m = { .v[0] = v0, .v[1] = v1, .v[2] = v2, .v[3] = v3 };
- return m;
-}
-
-c3mat4 c3mat4f(
- c3f a00, c3f a01, c3f a02, c3f a03,
- c3f a10, c3f a11, c3f a12, c3f a13,
- c3f a20, c3f a21, c3f a22, c3f a23,
- c3f a30, c3f a31, c3f a32, c3f a33 )
-{
- c3mat4 m;
- m.v[0] = c3vec4f(a00, a01, a01, a03);
- m.v[1] = c3vec4f(a10, a11, a11, a13);
- m.v[2] = c3vec4f(a20, a21, a21, a23);
- m.v[3] = c3vec4f(a30, a31, a21, a33);
- return m;
-}
-
-c3mat4p c3mat4p_add(c3mat4p a, const c3mat4p m)
-{
- a->v[0] = c3vec4_add(a->v[0], m->v[0]);
- a->v[1] = c3vec4_add(a->v[1], m->v[1]);
- a->v[2] = c3vec4_add(a->v[2], m->v[2]);
- a->v[3] = c3vec4_add(a->v[3], m->v[3]);
- return a;
-}
-
-c3mat4p c3mat4p_sub(c3mat4p a, const c3mat4p m)
-{
- a->v[0] = c3vec4_sub(a->v[0], m->v[0]);
- a->v[1] = c3vec4_sub(a->v[1], m->v[1]);
- a->v[2] = c3vec4_sub(a->v[2], m->v[2]);
- a->v[3] = c3vec4_sub(a->v[3], m->v[3]);
- return a;
-}
-
-c3mat4p c3mat4p_mulf(c3mat4p a, c3f d)
-{
- a->v[0] = c3vec4_mulf(a->v[0], d);
- a->v[1] = c3vec4_mulf(a->v[1], d);
- a->v[2] = c3vec4_mulf(a->v[2], d);
- a->v[3] = c3vec4_mulf(a->v[3], d);
- return a;
-}
-
-c3mat4p c3mat4p_divf(c3mat4p a, c3f d)
-{
- a->v[0] = c3vec4_divf(a->v[0], d);
- a->v[1] = c3vec4_divf(a->v[1], d);
- a->v[2] = c3vec4_divf(a->v[2], d);
- a->v[3] = c3vec4_divf(a->v[3], d);
- return a;
-}
-
-// SPECIAL FUNCTIONS;
-
-c3mat4 c3mat4_transpose(const c3mat4p a)
-{
- return c3mat4_vec4(
- c3vec4f(a->v[0].n[0], a->v[1].n[0], a->v[2].n[0], a->v[3].n[0]),
- c3vec4f(a->v[0].n[1], a->v[1].n[1], a->v[2].n[1], a->v[3].n[1]),
- c3vec4f(a->v[0].n[2], a->v[1].n[2], a->v[2].n[2], a->v[3].n[2]),
- c3vec4f(a->v[0].n[3], a->v[1].n[3], a->v[2].n[3], a->v[3].n[3]));
-}
-
-c3mat4 c3mat4_inverse(const c3mat4p m) // Gauss-Jordan elimination with partial pivoting
-{
- c3mat4 a = *m; // As a evolves from original mat into identity
- c3mat4 b = identity3D(); // b evolves from identity into inverse(a)
- int i, j, i1;
-
- // Loop over cols of a from left to right, eliminating above and below diag
- for (j = 0; j < 4; j++) { // Find largest pivot in column j among rows j..3
- i1 = j; // Row with largest pivot candidate
- for (i = j + 1; i < 4; i++)
- if (fabs(a.v[i].n[j]) > fabs(a.v[i1].n[j]))
- i1 = i;
-
- // Swap rows i1 and j in a and b to put pivot on diagonal
- c3vec4 _s;
- _s = a.v[i1]; a.v[i1] = a.v[j]; a.v[j] = _s; // swap(a.v[i1], a.v[j]);
- _s = b.v[i1]; b.v[i1] = b.v[j]; b.v[j] = _s; // swap(b.v[i1], b.v[j]);
-
- // Scale row j to have a unit diagonal
- if (a.v[j].n[j] == 0.) {
- // VEC_ERROR("c3mat4::inverse: singular matrix; can't invert\n");
- return a;
- }
- b.v[j] = c3vec4_divf(b.v[j], a.v[j].n[j]);
- a.v[j] = c3vec4_divf(a.v[j], a.v[j].n[j]);
-
- // Eliminate off-diagonal elems in col j of a, doing identical ops to b
- for (i = 0; i < 4; i++)
- if (i != j) {
- b.v[i] = c3vec4_sub(b.v[i], c3vec4_mulf(b.v[j], a.v[i].n[j]));
- a.v[i] = c3vec4_sub(a.v[i], c3vec4_mulf(a.v[j], a.v[i].n[j]));
- }
- }
-
- return b;
-}
-
-c3mat4p c3mat4p_apply(c3mat4p a, V_FCT_PTR fct)
-{
- a->v[0] = c3vec4_apply(a->v[0], fct);
- a->v[1] = c3vec4_apply(a->v[1], fct);
- a->v[2] = c3vec4_apply(a->v[2], fct);
- a->v[3] = c3vec4_apply(a->v[3], fct);
- return a;
-}
-
-c3mat4p c3mat4p_swap_rows(c3mat4p a, int i, int j)
-{
- c3vec4 t;
-
- t = a->v[i];
- a->v[i] = a->v[j];
- a->v[j] = t;
- return a;
-}
-
-c3mat4p c3mat4p_swap_cols(c3mat4p a, int i, int j)
-{
- c3f t;
-
- for (int k = 0; k < 4; k++) {
- t = a->v[k].n[i];
- a->v[k].n[i] = a->v[k].n[j];
- a->v[k].n[j] = t;
- }
- return a;
-}
-
-
-// FRIENDS
-
-c3mat4 c3mat4_minus(const c3mat4p a)
-{
- return c3mat4_vec4(
- c3vec4_minus(a->v[0]),
- c3vec4_minus(a->v[1]),
- c3vec4_minus(a->v[2]),
- c3vec4_minus(a->v[3]));
-}
-
-c3mat4 c3mat4_add(const c3mat4p a, const c3mat4p b)
-{
- return c3mat4_vec4(
- c3vec4_add(a->v[0], b->v[0]),
- c3vec4_add(a->v[1], b->v[1]),
- c3vec4_add(a->v[2], b->v[2]),
- c3vec4_add(a->v[3], b->v[3]));
-}
-
-c3mat4 c3mat4_sub(const c3mat4p a, const c3mat4p b)
-{
- return c3mat4_vec4(
- c3vec4_sub(a->v[0], b->v[0]),
- c3vec4_sub(a->v[1], b->v[1]),
- c3vec4_sub(a->v[2], b->v[2]),
- c3vec4_sub(a->v[3], b->v[3]));
-}
-
-c3mat4 c3mat4_mul(const c3mat4p a, const c3mat4p b)
-{
- #define ROWCOL(i, j) \
- a->v[i].n[0]*b->v[0].n[j] + \
- a->v[i].n[1]*b->v[1].n[j] + \
- a->v[i].n[2]*b->v[2].n[j] + \
- a->v[i].n[3]*b->v[3].n[j]
-
- return c3mat4_vec4(
- c3vec4f(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2), ROWCOL(0,3)),
- c3vec4f(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2), ROWCOL(1,3)),
- c3vec4f(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2), ROWCOL(2,3)),
- c3vec4f(ROWCOL(3,0), ROWCOL(3,1), ROWCOL(3,2), ROWCOL(3,3))
- );
-
- #undef ROWCOL
-}
-
-c3mat4 c3mat4_mulf(const c3mat4p a, c3f d)
-{
- c3mat4 r = *a;
- return *c3mat4p_mulf(&r, d);
-}
-
-c3mat4 c3mat4_divf(const c3mat4p a, c3f d)
-{
- c3mat4 r = *a;
- return *c3mat4p_divf(&r, d);
-}
-
-int c3mat4_equal(const c3mat4p a, const c3mat4p b)
-{
- return !memcmp(a->n, b->n, sizeof(a->n));
-#if 0
- return
- c3vec4_equal(a->v[0], b->v[0]) &&
- c3vec4_equal(a->v[1], b->v[1]) &&
- c3vec4_equal(a->v[2], b->v[2]) &&
- c3vec4_equal(a->v[3], b->v[3]);
-#endif
-}
-
-/****************************************************************
- * *
- * 2D functions and 3D functions *
- * *
- ****************************************************************/
-
-c3mat3 identity2D()
-{
- return c3mat3_vec3(
- c3vec3f(1.0, 0.0, 0.0),
- c3vec3f(0.0, 1.0, 0.0),
- c3vec3f(0.0, 0.0, 1.0));
-}
-
-c3mat3 translation2D(const c3vec2 v)
-{
- return c3mat3_vec3(
- c3vec3f(1.0, 0.0, v.n[VX]),
- c3vec3f(0.0, 1.0, v.n[VY]),
- c3vec3f(0.0, 0.0, 1.0));
-}
-
-c3mat3 rotation2D(const c3vec2 Center, c3f angleDeg)
-{
- c3f angleRad = (c3f) (angleDeg * PI_OVER_180);
- c3f c = (c3f) cos(angleRad);
- c3f s = (c3f) sin(angleRad);
-
- return c3mat3_vec3(
- c3vec3f(c, -s, Center.n[VX] * (1.0f-c) + Center.n[VY] * s),
- c3vec3f(s, c, Center.n[VY] * (1.0f-c) - Center.n[VX] * s),
- c3vec3f(0.0, 0.0, 1.0));
-}
-
-c3mat3 scaling2D(const c3vec2 scaleVector)
-{
- return c3mat3_vec3(
- c3vec3f(scaleVector.n[VX], 0.0, 0.0),
- c3vec3f(0.0, scaleVector.n[VY], 0.0),
- c3vec3f(0.0, 0.0, 1.0));
-}
-
-c3mat4
-identity3D()
-{
- return c3mat4_vec4(
- c3vec4f(1.0, 0.0, 0.0, 0.0),
- c3vec4f(0.0, 1.0, 0.0, 0.0),
- c3vec4f(0.0, 0.0, 1.0, 0.0),
- c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 translation3D(const c3vec3 v)
-{
- return c3mat4_vec4(
- c3vec4f(1.0, 0.0, 0.0, 0.0),
- c3vec4f(0.0, 1.0, 0.0, 0.0),
- c3vec4f(0.0, 0.0, 1.0, 0.0),
- c3vec4f(v.n[VX], v.n[VY], v.n[VZ], 1.0));
-}
-
-c3mat4 rotation3D(const c3vec3 Axis, c3f angleDeg)
-{
- c3f angleRad = (c3f) (angleDeg * PI_OVER_180);
- c3f c = (c3f) cos(angleRad);
- c3f s = (c3f) sin(angleRad);
- c3f t = 1.0f - c;
-
- c3vec3 axis = c3vec3_normalize(Axis);
-
- return c3mat4_vec4(
- c3vec4f(
- t * axis.n[VX] * axis.n[VX] + c,
- t * axis.n[VX] * axis.n[VY] - s * axis.n[VZ],
- t * axis.n[VX] * axis.n[VZ] + s * axis.n[VY],
- 0.0),
- c3vec4f(
- t * axis.n[VX] * axis.n[VY] + s * axis.n[VZ],
- t * axis.n[VY] * axis.n[VY] + c,
- t * axis.n[VY] * axis.n[VZ] - s * axis.n[VX],
- 0.0),
- c3vec4f(
- t * axis.n[VX] * axis.n[VZ] - s * axis.n[VY],
- t * axis.n[VY] * axis.n[VZ] + s * axis.n[VX],
- t * axis.n[VZ] * axis.n[VZ] + c,
- 0.0),
- c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 rotation3Drad(const c3vec3 Axis, c3f angleRad)
-{
- c3f c = (c3f) cos(angleRad);
- c3f s = (c3f) sin(angleRad);
- c3f t = 1.0f - c;
-
- c3vec3 axis = c3vec3_normalize(Axis);
-
- return c3mat4_vec4(
- c3vec4f(t * axis.n[VX] * axis.n[VX] + c,
- t * axis.n[VX] * axis.n[VY] - s * axis.n[VZ],
- t * axis.n[VX] * axis.n[VZ] + s * axis.n[VY],
- 0.0),
- c3vec4f(t * axis.n[VX] * axis.n[VY] + s * axis.n[VZ],
- t * axis.n[VY] * axis.n[VY] + c,
- t * axis.n[VY] * axis.n[VZ] - s * axis.n[VX],
- 0.0),
- c3vec4f(t * axis.n[VX] * axis.n[VZ] - s * axis.n[VY],
- t * axis.n[VY] * axis.n[VZ] + s * axis.n[VX],
- t * axis.n[VZ] * axis.n[VZ] + c,
- 0.0),
- c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 scaling3D(const c3vec3 scaleVector)
-{
- return c3mat4_vec4(
- c3vec4f(scaleVector.n[VX], 0.0, 0.0, 0.0),
- c3vec4f(0.0, scaleVector.n[VY], 0.0, 0.0),
- c3vec4f(0.0, 0.0, scaleVector.n[VZ], 0.0),
- c3vec4f(0.0, 0.0, 0.0, 1.0));
-}
-
-c3mat4 frustum3D(
- c3f left, c3f right, c3f bottom, c3f top,
- c3f znear, c3f zfar)
-{
- c3f temp = 2.0 * znear,
- temp2 = right - left,
- temp3 = top - bottom,
- temp4 = zfar - znear;
- return c3mat4_vec4(
- c3vec4f(temp / temp2, 0.0, 0.0, 0.0),
- c3vec4f(0.0, temp / temp3, 0.0, 0.0),
- c3vec4f((right + left) / temp2, (top + bottom) / temp3, (-zfar - znear) / temp4, -1.0),
- c3vec4f(-1.0, 0.0, (-temp * zfar) / temp4, 0.0));
-}
-
-c3mat4 perspective3D(c3f fov, c3f aspect, c3f zNear, c3f zFar)
-{
- c3f ymax = zNear * tan(fov * PI_OVER_360);
- c3f ymin = -ymax;
- c3f xmin = ymin * aspect;
- c3f xmax = ymax * aspect;
-
- return frustum3D(xmin, xmax, ymin, ymax, zNear, zFar);
-}
-
-c3mat4 ortho3D(
- c3f left, c3f right, c3f bottom, c3f top,
- c3f near, c3f far)
-{
- c3f a = 2.0f / (right - left);
- c3f b = 2.0f / (top - bottom);
- c3f c = -2.0f / (far - near);
-
- c3f tx = - (right + left)/(right - left);
- c3f ty = - (top + bottom)/(top - bottom);
- c3f tz = - (far + near)/(far - near);
-
- float ortho[16] = {
- a, 0, 0, 0,
- 0, b, 0, 0,
- 0, 0, c, 0,
- tx, ty, tz, 1
- };
- return *((c3mat4p)ortho);
-}
-
-/*
- * Same as previous, but this one is screen aligned, with 0,0 being top,left
- * instead of bottom,left
- */
-c3mat4 screen_ortho3D(
- c3f left, c3f right, c3f bottom, c3f top,
- c3f near, c3f far)
-{
- c3f a = 2.0f / (right - left);
- c3f b = 2.0f / (top - bottom);
- c3f c = -2.0f / (far - near);
-
- c3f tx = - (right + left)/(right - left);
- c3f ty = - (top + bottom)/(top - bottom);
- c3f tz = - (far + near)/(far - near);
-
- float ortho[16] = {
- a, 0, 0, 0,
- 0, -b, 0, 0,
- 0, 0, c, 0,
- tx, -ty, tz, 1
- };
- return *((c3mat4p)ortho);
-}
+++ /dev/null
-/*
- c3algebra.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- Derivative and inspiration from original C++:
- Paul Rademacher & Jean-Francois DOUEG,
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3ALGEBRA_H___
-#define __C3ALGEBRA_H___
-
-
-#ifndef M_PI
-#define M_PI 3.141592654
-#endif
-#define PI_OVER_180 0.017453292519943295769236907684886
-#define PI_OVER_360 0.0087266462599716478846184538424431
-
-enum {VX, VY, VZ, VW}; // axes
-enum {PA, PB, PC, PD}; // planes
-enum {RED, GREEN, BLUE, ALPHA}; // colors
-enum {KA, KD, KS, ES}; // phong coefficients
-
-typedef float c3f;
-typedef c3f (*V_FCT_PTR)(c3f);
-
-typedef union c3vec2 {
- struct { c3f x,y; };
- c3f n[2];
-} c3vec2;
-
-typedef union c3vec3 {
- struct { c3f x,y,z; };
- c3f n[3];
-} c3vec3;
-
-typedef union c3vec4 {
- struct { c3f x,y,z,w; };
- c3f n[4];
-} c3vec4, * c3vec4p;
-
-typedef union c3mat3 {
- c3vec3 v[3];
- c3f n[3*3];
-} c3mat3, * c3mat3p;
-
-typedef union c3mat4 {
- c3vec4 v[4];
- c3f n[4*4];
-} c3mat4, * c3mat4p;
-
-/*
- * c3vec2 related
- */
-
-c3vec2 c3vec2_zero();
-c3vec2 c3vec2f(c3f x, c3f y);
-
-c3vec2 c3vec2_add(c3vec2 a, const c3vec2 v);
-c3vec2 c3vec2_sub(c3vec2 a, const c3vec2 v);
-c3vec2 c3vec2_mulf(c3vec2 a, c3f d);
-c3vec2 c3vec2_divf(c3vec2 a, c3f d);
-
-c3f c3vec2_length2(const c3vec2 a);
-c3f c3vec2_length(const c3vec2 a);
-c3vec2 c3vec2_normalize(const c3vec2 a); // it is up to caller to avoid divide-by-zero
-c3vec2 c3vec2_apply(c3vec2 a, V_FCT_PTR fct);
-c3vec2 c3vec2_minus(const c3vec2 a);
-c3f c3vec2_dot(const c3vec2 a, const c3vec2 b);
-c3vec2 c3vec2_min(const c3vec2 a, const c3vec2 b);
-c3vec2 c3vec2_max(const c3vec2 a, const c3vec2 b);
-c3vec2 c3vec2_prod(const c3vec2 a, const c3vec2 b);
-
-/*
- * c3vec3 related
- */
-
-c3vec3 c3vec3_zero();
-c3vec3 c3vec3f(c3f x, c3f y, c3f z);
-c3vec3 c3vec3_vec2f(const c3vec2 v, c3f d);
-c3vec3 c3vec3_vec2(const c3vec2 v);
-c3vec3 c3vec3_vec4(const c3vec4 v); // it is up to caller to avoid divide-by-zero
-
-c3vec3 c3vec3_add(const c3vec3 a, const c3vec3 v);
-c3vec3 c3vec3_sub(const c3vec3 a, const c3vec3 v);
-c3vec3 c3vec3_mulf(const c3vec3 a, c3f d);
-c3vec3 c3vec3_divf(const c3vec3 a, c3f d);
-
-c3f c3vec3_length2(const c3vec3 a);
-c3f c3vec3_length(const c3vec3 a);
-c3vec3 c3vec3_normalize(const c3vec3 a); // it is up to caller to avoid divide-by-zero
-c3vec3 c3vec3_homogenize(c3vec3 a); // it is up to caller to avoid divide-by-zero
-c3vec3 c3vec3_apply(c3vec3 a, V_FCT_PTR fct);
-c3vec3 c3vec3_minus(const c3vec3 a);
-c3f c3vec3_dot(const c3vec3 a, const c3vec3 b);
-int c3vec3_equal(const c3vec3 a, const c3vec3 b);
-c3vec3 c3vec3_min(const c3vec3 a, const c3vec3 b);
-c3vec3 c3vec3_max(const c3vec3 a, const c3vec3 b);
-c3vec3 c3vec3_prod(const c3vec3 a, const c3vec3 b);
-
-c3vec3 c3vec3_cross(const c3vec3 a, const c3vec3 b);
-c3vec3 c3vec2_cross(const c3vec2 a, const c3vec2 b);
-c3vec3 c3vec3_polar(const c3vec3 a); // returns phi, theta, length
-
-/*
- * c3vec4 related
- */
-
-c3vec4 c3vec4_zero();
-c3vec4 c3vec4f(c3f x, c3f y, c3f z, c3f w);
-c3vec4 c3vec4_vec3(const c3vec3 v);
-c3vec4 c3vec4_vec3f(const c3vec3 v, c3f d);
-
-c3vec4 c3vec4_add(c3vec4 a, const c3vec4 v);
-c3vec4 c3vec4_sub(c3vec4 a, const c3vec4 v);
-c3vec4 c3vec4_mulf(c3vec4 a, c3f d);
-c3vec4 c3vec4_divf(c3vec4 a, c3f d);
-
-c3f c3vec4_length2(const c3vec4 a);
-c3f c3vec4_length(const c3vec4 a);
-c3vec4 c3vec4_normalize(c3vec4 a); // it is up to caller to avoid divide-by-zero
-c3vec4 c3vec4_homogenize(c3vec4 a); // it is up to caller to avoid divide-by-zero
-c3vec4 c3vec4_apply(c3vec4 a, V_FCT_PTR fct);
-c3vec4 c3vec4_minus(const c3vec4 a);
-int c3vec4_equal(const c3vec4 a, const c3vec4 b);
-c3vec4 c3vec4_min(const c3vec4 a, const c3vec4 b);
-c3vec4 c3vec4_max(const c3vec4 a, const c3vec4 b);
-c3vec4 c3vec4_prod(const c3vec4 a, const c3vec4 b);
-
-/*
- * c3mat3 related
- */
-
-c3mat3 c3mat3_identity();
-c3mat3 c3mat3_vec3(const c3vec3 v0, const c3vec3 v1, const c3vec3 v2);
-c3mat3p c3mat3_add(const c3mat3p a, const c3mat3p m);
-c3mat3p c3mat3_sub(const c3mat3p a, const c3mat3p m);
-c3mat3p c3mat3_mulf(const c3mat3p a, c3f d);
-c3mat3p c3mat3_divf(const c3mat3p a, c3f d);
-
-c3mat3 c3mat3_transpose(const c3mat3p a);
-c3mat3 c3mat3_inverse(const c3mat3p m); // Gauss-Jordan elimination with partial pivoting
-c3mat3p c3mat3_apply(c3mat3p a, V_FCT_PTR fct);
-c3mat3 c3mat3_minus(const c3mat3p a);
-
-c3mat3 c3mat3_mul(const c3mat3p a, const c3mat3p b);
-int c3mat3_equal(const c3mat3p a, const c3mat3p b);
-
-c3vec2 c3mat3_mulv2(const c3mat3p a, const c3vec2 v);
-c3vec3 c3mat3_mulv3(const c3mat3p a, const c3vec3 v);
-c3vec2 c3vec2_mulm3(const c3vec2 v, const c3mat3p a);
-c3vec3 c3vec3_mulm3(const c3vec3 v, const c3mat3p a);
-
-c3mat3 identity2D();
-c3mat3 translation2D(const c3vec2 v);
-c3mat3 rotation2D(const c3vec2 Center, c3f angleDeg);
-c3mat3 scaling2D(const c3vec2 scaleVector);
-
-/*
- * c3mat4 related
- */
-
-c3mat4 c3mat4_identity();
-c3mat4 c3mat4_vec4(const c3vec4 v0, const c3vec4 v1, const c3vec4 v2, const c3vec4 v3);
-c3mat4 c3mat4f(
- c3f a00, c3f a01, c3f a02, c3f a03,
- c3f a10, c3f a11, c3f a12, c3f a13,
- c3f a20, c3f a21, c3f a22, c3f a23,
- c3f a30, c3f a31, c3f a32, c3f a33 );
-
-c3mat4 c3mat4_minus(const c3mat4p a);
-c3mat4p c3mat4p_add(c3mat4p a, const c3mat4p m);
-c3mat4 c3mat4_add(const c3mat4p a, const c3mat4p b);
-c3mat4p c3mat4p_sub(c3mat4p a, const c3mat4p m);
-c3mat4 c3mat4_sub(const c3mat4p a, const c3mat4p b);
-c3mat4p c3mat4p_mulf(c3mat4p a, c3f d);
-c3mat4 c3mat4_mulf(const c3mat4p a, c3f d);
-c3mat4 c3mat4_mul(const c3mat4p a, const c3mat4p b);
-c3mat4p c3mat4p_divf(c3mat4p a, c3f d);
-c3mat4 c3mat4_divf(const c3mat4p a, c3f d);
-
-c3mat4 c3mat4_transpose(const c3mat4p a);
-c3mat4 c3mat4_inverse(const c3mat4p m); // Gauss-Jordan elimination with partial pivoting
-c3mat4p c3mat4p_apply(c3mat4p a, V_FCT_PTR fct);
-c3mat4p c3mat4p_swap_rows(c3mat4p a, int i, int j);
-c3mat4p c3mat4p_swap_cols(c3mat4p a, int i, int j);
-int c3mat4_equal(const c3mat4p a, const c3mat4p b);
-
-c3vec4 c3vec4_mulm4(const c3vec4 v, const c3mat4p a);
-c3vec4 c3mat4_mulv4(const c3mat4p a, const c3vec4 v);
-c3vec3 c3mat4_mulv3(const c3mat4p a, const c3vec3 v);
-
-c3mat4 identity3D();
-c3mat4 translation3D(const c3vec3 v);
-c3mat4 rotation3D(const c3vec3 Axis, c3f angleDeg);
-c3mat4 rotation3Drad(const c3vec3 Axis, c3f angleRad);
-c3mat4 scaling3D(const c3vec3 scaleVector);
-c3mat4 frustum3D(
- c3f left, c3f right, c3f bottom, c3f top,
- c3f znear, c3f zfar);
-c3mat4 perspective3D(c3f fov, c3f aspect, c3f znear, c3f zfar);
-c3mat4 ortho3D(
- c3f left, c3f right, c3f bottom, c3f top,
- c3f near, c3f far);
-c3mat4 screen_ortho3D(
- c3f left, c3f right, c3f bottom, c3f top,
- c3f near, c3f far);
-
-#endif /* __C3ALGEBRA_H___ */
+++ /dev/null
-/*
- c3arcball.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include "c3arcball.h"
-
-
-/**************************************** c3arcball_init_mat4() ****/
-/* Takes as argument a c3mat4 to use instead of the internal rot */
-
-void
-c3arcball_init_mat4(
- c3arcballp a,
- c3mat4p mtx )
-{
- c3arcball_init(a);
- a->rot_ptr = mtx;
-}
-
-
-/**************************************** c3arcball_init_center() ****/
-/* A constructor that accepts the screen center and arcball radius*/
-
-void
-c3arcball_init_center(
- c3arcballp a,
- const c3vec2 center,
- c3f radius )
-{
- c3arcball_init(a);
- c3arcball_set_params(a, center, radius);
-}
-
-
-/************************************** c3arcball_set_params() ****/
-
-void
-c3arcball_set_params(
- c3arcballp a,
- const c3vec2 center,
- c3f radius)
-{
- a->center = center;
- a->radius = radius;
-}
-
-/*************************************** c3arcball_init() **********/
-
-void
-c3arcball_init(
- c3arcballp a )
-{
- a->center = c3vec2f( 0.0, 0.0 );
- a->radius = 1.0;
- a->q_now = c3quat_identity();
- a->rot_ptr = &a->rot;
- a->rot = identity3D();
- a->q_increment = c3quat_identity();
- a->rot_increment = identity3D();
- a->is_mouse_down = false;
- a->is_spinning = false;
- a->damp_factor = 0.0;
- a->zero_increment = true;
-}
-
-/*********************************** c3arcball_mouse_to_sphere() ****/
-
-c3vec3
-c3arcball_mouse_to_sphere(
- c3arcballp a,
- const c3vec2 p)
-{
- c3f mag;
- c3vec2 v2 = c3vec2_divf(c3vec2_sub(p, a->center), a->radius);
- c3vec3 v3 = c3vec3f( v2.n[0], v2.n[1], 0.0 );
-
- mag = c3vec2_dot(v2, v2);
-
- if ( mag > 1.0 )
- v3 = c3vec3_normalize(v3);
- else
- v3.n[VZ] = (c3f) sqrt( 1.0 - mag );
-
- /* Now we add constraints - X takes precedence over Y */
- if ( a->constraint_x ) {
- v3 = c3arcball_constrain_vector( v3, c3vec3f( 1.0, 0.0, 0.0 ));
- } else if ( a->constraint_y ) {
- v3 = c3arcball_constrain_vector( v3, c3vec3f( 0.0, 1.0, 0.0 ));
- }
-
- return v3;
-}
-
-
-/************************************ c3arcball_constrain_vector() ****/
-
-c3vec3
-c3arcball_constrain_vector(
- const c3vec3 vector,
- const c3vec3 axis)
-{
-// return (vector - (vector * axis) * axis).normalize();
- return vector;
-}
-
-/************************************ c3arcball_mouse_down() **********/
-
-void
-c3arcball_mouse_down(
- c3arcballp a,
- int x,
- int y)
-{
- a->down_pt = c3vec2f( (c3f)x, (c3f) y );
- a->is_mouse_down = true;
-
- a->q_increment = c3quat_identity();
- a->rot_increment = identity3D();
- a->zero_increment = true;
-}
-
-
-/************************************ c3arcball_mouse_up() **********/
-
-void
-c3arcball_mouse_up(
- c3arcballp a)
-{
- a->q_now = c3quat_mul(a->q_drag, a->q_now);
- a->is_mouse_down = false;
-}
-
-
-/********************************** c3arcball_mouse_motion() **********/
-
-void
-c3arcball_mouse_motion(
- c3arcballp a,
- int x,
- int y,
- int shift,
- int ctrl,
- int alt)
-{
- /* Set the X constraint if CONTROL key is pressed, Y if ALT key */
- c3arcball_set_constraints(a, ctrl != 0, alt != 0 );
-
- c3vec2 new_pt = c3vec2f( (c3f)x, (c3f) y );
- c3vec3 v0 = c3arcball_mouse_to_sphere(a, a->down_pt );
- c3vec3 v1 = c3arcball_mouse_to_sphere(a, new_pt );
-
- c3vec3 cross = c3vec3_cross(v0, v1);
-
- a->q_drag = c3quat_vec3(cross, c3vec3_dot(v0, v1));
-
- // *rot_ptr = (q_drag * q_now).to_mat4();
- c3mat4 temp = c3quat_to_mat4(a->q_drag);
- *a->rot_ptr = c3mat4_mul(a->rot_ptr, &temp);
-
- a->down_pt = new_pt;
-
- /* We keep a copy of the current incremental rotation (= q_drag) */
- a->q_increment = a->q_drag;
- a->rot_increment = c3quat_to_mat4(a->q_increment);
-
- c3arcball_set_constraints(a, false, false);
-
- if (a->q_increment.s < .999999) {
- a->is_spinning = true;
- a->zero_increment = false;
- } else {
- a->is_spinning = false;
- a->zero_increment = true;
- }
-}
-
-
-/********************************** c3arcball_mouse_motion() **********/
-#if 0
-void
-c3arcball_mouse_motion(
- c3arcballp a,
- int x,
- int y)
-{
- mouse_motion(x, y, 0, 0, 0);
-}
-#endif
-
-/***************************** c3arcball_set_constraints() **********/
-
-void
-c3arcball_set_constraints(
- c3arcballp a,
- bool _constraint_x,
- bool _constraint_y)
-{
- a->constraint_x = _constraint_x;
- a->constraint_y = _constraint_y;
-}
-
-/***************************** c3arcball_idle() *********************/
-
-void
-c3arcball_idle(
- c3arcballp a)
-{
- if (a->is_mouse_down) {
- a->is_spinning = false;
- a->zero_increment = true;
- }
-
- if (a->damp_factor < 1.0f)
- c3quat_scale_angle(&a->q_increment, 1.0f - a->damp_factor);
-
- a->rot_increment = c3quat_to_mat4(a->q_increment);
-
- if (a->q_increment.s >= .999999f) {
- a->is_spinning = false;
- a->zero_increment = true;
- }
-}
-
-
-/************************ c3arcball_set_damping() *********************/
-
-void
-c3arcball_set_damping(
- c3arcballp a,
- c3f d)
-{
- a->damp_factor = d;
-}
-
-
-
+++ /dev/null
-/*
- c3arcball.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
- Copyright (c) 1998 Paul Rademacher
- Feb 1998, Paul Rademacher (rademach@cs.unc.edu)
- Oct 2003, Nigel Stewart - GLUI Code Cleaning
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- Arcball, as described by Ken
- Shoemake in Graphics Gems IV.
- This class takes as input mouse events (mouse down, mouse drag,
- mouse up), and creates the appropriate quaternions and 4x4 matrices
- to represent the rotation given by the mouse.
-
- This class is used as follows:
- - initialize [either in the constructor or with set_params()], the
- center position (x,y) of the arcball on the screen, and the radius
- - on mouse down, call mouse_down(x,y) with the mouse position
- - as the mouse is dragged, repeatedly call mouse_motion() with the
- current x and y positions. One can optionally pass in the current
- state of the SHIFT, ALT, and CONTROL keys (passing zero if keys
- are not pressed, non-zero otherwise), which constrains
- the rotation to certain axes (X for CONTROL, Y for ALT).
- - when the mouse button is released, call mouse_up()
-
- Axis constraints can also be explicitly set with the
- set_constraints() function.
-
- The current rotation is stored in the 4x4 float matrix 'rot'.
- It is also stored in the quaternion 'q_now'.
- */
-
-#ifndef __C3ARCBALL_H___
-#define __C3ARCBALL_H___
-
-#include "c3quaternion.h"
-
-typedef struct c3arcball {
- int is_mouse_down : 1, /* true for down, false for up */
- is_spinning : 1,
- constraint_x : 1,
- constraint_y : 1,
- zero_increment : 1;
- c3quat q_now, q_down, q_drag, q_increment;
- c3vec2 down_pt;
- c3mat4 rot, rot_increment;
- c3mat4 *rot_ptr;
-
- c3vec2 center;
- c3f radius, damp_factor;
-} c3arcball, *c3arcballp;
-
-void
-c3arcball_init(
- c3arcballp a );
-void
-c3arcball_init_mat4(
- c3arcballp a,
- c3mat4p mtx );
-void
-c3arcball_init_center(
- c3arcballp a,
- const c3vec2 center,
- c3f radius );
-void
-c3arcball_set_params(
- c3arcballp a,
- const c3vec2 center,
- c3f radius);
-c3vec3
-c3arcball_mouse_to_sphere(
- c3arcballp a,
- const c3vec2 p);
-c3vec3
-c3arcball_constrain_vector(
- const c3vec3 vector,
- const c3vec3 axis);
-void
-c3arcball_mouse_down(
- c3arcballp a,
- int x,
- int y);
-void
-c3arcball_mouse_up(
- c3arcballp a);
-
-void
-c3arcball_mouse_motion(
- c3arcballp a,
- int x,
- int y,
- int shift,
- int ctrl,
- int alt);
-void
-c3arcball_set_constraints(
- c3arcballp a,
- bool _constraint_x,
- bool _constraint_y);
-void
-c3arcball_idle(
- c3arcballp a);
-void
-c3arcball_set_damping(
- c3arcballp a,
- c3f d);
-
-#endif /* __C3ARCBALL_H___ */
+++ /dev/null
-/*
- c3cairo.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3cairo.h"
-#include "c3driver_geometry.h"
-
-#if CONFIG_C3_CAIRO
-
-void
-_c3cairo_dispose(
- c3geometry_p g,
- const c3driver_geometry_t * d)
-{
- c3cairo_p c = (c3cairo_p)g;
-
- if (c->cr)
- cairo_destroy(c->cr);
- if (c->surface)
- cairo_surface_destroy(c->surface);
- C3_DRIVER_INHERITED(g, d, dispose);
-}
-
-static void
-_c3cairo_project(
- c3geometry_p g,
- const struct c3driver_geometry_t *d,
- c3mat4p m)
-{
- C3_DRIVER_INHERITED(g, d, project, m);
-}
-
-const c3driver_geometry_t c3cairo_base_driver = {
- .dispose = _c3cairo_dispose,
- .project = _c3cairo_project,
-};
-extern const c3driver_geometry_t c3texture_driver;
-extern const c3driver_geometry_t c3geometry_driver;
-
-c3cairo_p
-c3cairo_new(
- struct c3object_t * parent)
-{
- c3cairo_p res = malloc(sizeof(*res));
- return c3cairo_init(res, parent);
-}
-
-c3cairo_p
-c3cairo_init(
- c3cairo_p o,
- struct c3object_t * parent)
-{
- memset(o, 0, sizeof(*o));
- c3texture_init(&o->tex, parent);
-
- static const c3driver_geometry_t * list[] = {
- &c3cairo_base_driver, &c3texture_driver, &c3geometry_driver, NULL,
- };
- ((c3geometry_p)o)->driver = list;
-
- return o;
-}
-
-c3cairo_p
-c3cairo_new_offscreen(
- struct c3object_t * parent,
- int w, int h)
-{
- c3cairo_p o = c3cairo_new(parent);
-
- o->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
- o->cr = cairo_create(o->surface);
-
- c3pixels_p dst = c3pixels_new(w, h, 4,
- cairo_image_surface_get_stride(o->surface),
- cairo_image_surface_get_data(o->surface));
- o->tex.geometry.mat.texture = dst;
-
- return o;
-}
-
-#if 0
-cairo_surface_destroy(_surface);
-else
-cairo_surface_finish(_surface);
-#endif
-#endif // CONFIG_C3_CAIRO
+++ /dev/null
-/*
- c3cairo.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3CAIRO_H___
-#define __C3CAIRO_H___
-
-#include "c3config.h"
-#include "c3texture.h"
-#include "c3pixels.h"
-
-#if CONFIG_C3_CAIRO
-#include <pango/pangocairo.h>
-
-typedef struct c3cairo_t {
- c3texture_t tex;
- cairo_t * cr;
- cairo_surface_t * surface;
-} c3cairo_t, *c3cairo_p;
-
-c3cairo_p
-c3cairo_new(
- struct c3object_t * parent /* = NULL */);
-
-c3cairo_p
-c3cairo_init(
- c3cairo_p o,
- struct c3object_t * parent /* = NULL */);
-
-c3cairo_p
-c3cairo_new_offscreen(
- struct c3object_t * parent /* = NULL */,
- int w, int h);
-
-#endif // CONFIG_C3_CAIRO
-
-#endif /* __C3CAIRO_H___ */
+++ /dev/null
-/*
- c3camera.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
- Copyright (c) 1998 Paul Rademacher
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-#include "c3camera.h"
-
-
-void
-c3cam_set_distance(
- c3cam_p c,
- const c3f new_distance)
-{
- if ( new_distance <= 0.0 ) /* Distance has to be positive */
- return;
-
- /* We find the current forward vector */
-// forward = lookat - eye;
- c->forward = c3vec3_normalize(c3vec3_sub(c->lookat, c->eye));
-
- /* Set distance */
- c->distance = new_distance;
-
- /* Find new eye point */
- c->eye = c3vec3_sub(c->lookat, c3vec3_mulf(c->forward, c->distance));
- c3cam_update(c);
-}
-
-void
-c3cam_set_upv(
- c3cam_p c,
- const c3vec3 new_up)
-{
- c->up = new_up;
- c3cam_update(c);
-}
-
-void
-c3cam_set_upf(
- c3cam_p c,
- const c3f x,
- const c3f y,
- const c3f z)
-{
- c3cam_set_upv(c, c3vec3f(x,y,z));
-}
-
-void
-c3cam_set_eyev(
- c3cam_p c,
- const c3vec3 new_eye)
-{
- c->eye = new_eye;
- c3cam_update(c);
-}
-
-void
-c3cam_set_eyef(
- c3cam_p c,
- const c3f x,
- const c3f y,
- const c3f z)
-{
- c3cam_set_eyev(c, c3vec3f(x,y,z));
-}
-
-void
-c3cam_set_lookatv(
- c3cam_p c,
- const c3vec3 new_lookat)
-{
- c->lookat = new_lookat;
- c3cam_update(c);
-}
-
-void
-c3cam_set_lookatf(
- c3cam_p c,
- const c3f x,
- const c3f y,
- const c3f z)
-{
- c3cam_set_lookatv(c, c3vec3f(x,y,z));
-}
-
-
-void
-c3cam_roll(
- c3cam_p c,
- const c3f angle)
-{
- c3mat4 rot = rotation3D(c->forward, angle );
- c->up = c3mat4_mulv3(&rot, c->up);
- c3cam_update(c);
-}
-
-void
-c3cam_eye_yaw(
- c3cam_p c,
- const c3f angle)
-{
- c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
- c3mat4 rot = rotation3D( c->up, angle );
-
- eye_pt = c3mat4_mulv3(&rot, eye_pt);
- c->eye = c3vec3_add(c->lookat, eye_pt);
-
- c3cam_update(c);
-}
-
-void
-c3cam_eye_yaw_abs(
- c3cam_p c,
- const c3f angle,
- const c3vec3 axis)
-{
- c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
- c3mat4 rot = rotation3D( axis, angle );
-
- eye_pt = c3mat4_mulv3(&rot, eye_pt);
- c->eye = c3vec3_add(c->lookat, eye_pt);
-
- c->up = c3mat4_mulv3(&rot, c->up);
-
- c3cam_update(c);
-}
-
-
-void
-c3cam_eye_pitch(
- c3cam_p c,
- const c3f angle)
-{
- c3vec3 eye_pt = c3vec3_sub(c->eye, c->lookat); /* eye w/lookat at center */
- c3mat4 rot = rotation3D( c->side, angle );
-
- eye_pt = c3mat4_mulv3(&rot, eye_pt);
- c->eye = c3vec3_add(c->lookat, eye_pt);
-
- c->up = c3mat4_mulv3(&rot, c->up);
-
- c3cam_update(c);
-}
-
-void
-c3cam_lookat_yaw(
- c3cam_p c,
- const c3f angle)
-{
- c3vec3 lookat_pt = c3vec3_sub(c->lookat, c->eye); /* lookat w/eye at center */
- c3mat4 rot = rotation3D( c->up, -angle );
-
- lookat_pt = c3mat4_mulv3(&rot, lookat_pt);
- c->lookat = c3vec3_add(c->eye, lookat_pt);
-
- c3cam_update(c);
-}
-
-void
-c3cam_lookat_pitch(
- c3cam_p c,
- const c3f angle)
-{
- c3vec3 lookat_pt = c3vec3_sub(c->lookat, c->eye); /* lookat w/eye at center */
- c3mat4 rot = rotation3D( c->side, -angle );
-
- lookat_pt = c3mat4_mulv3(&rot, lookat_pt);
- c->lookat = c3vec3_add(c->eye, lookat_pt);
-
- c->up = c3mat4_mulv3(&rot, c->up);
-
- c3cam_update(c);
-}
-
-void
-c3cam_reset_up_axis(
- c3cam_p c,
- const int axis_num)
-{
- c3vec3 eye_pt = c3vec3_sub(c->lookat, c->eye); /* eye w/lookat at center */
- c3f eye_distance = c3vec3_length(eye_pt);
- c->eye.n[axis_num] = c->lookat.n[axis_num];
- /* Bring eye to same level as lookat */
-
- c3vec3 vector = c3vec3_sub(c->eye, c->lookat);
- vector = c3vec3_normalize(vector);
- vector = c3vec3_mulf(vector, eye_distance);
-
- c->eye = c3vec3_add(c->lookat, vector);
- c->up = c3vec3f( 0.0, 0.0, 0.0 );
- c->up.n[axis_num] = 1.0;
-
- c3cam_update(c);
-}
-
-void
-c3cam_reset_up(
- c3cam_p c)
-{
- c3cam_reset_up_axis(c, VY ); /* Resets to the Y axis */
-}
-
-void
-c3cam_movef(
- c3cam_p c,
- const c3f side_move,
- const c3f up_move,
- const c3f forw_move)
-{
- c->eye = c3vec3_add(c->eye, c3vec3_mulf(c->forward, forw_move));
- c->eye = c3vec3_add(c->eye, c3vec3_mulf(c->side, side_move));
- c->eye = c3vec3_add(c->eye, c3vec3_mulf(c->up, up_move));
- c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->forward, forw_move));
- c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->side, side_move));
- c->lookat = c3vec3_add(c->lookat, c3vec3_mulf(c->up, up_move));
- c3cam_update(c);
-}
-
-void
-c3cam_movev(
- c3cam_p c,
- const c3vec3 v) /* A vector version of the above command */
-{
- c3cam_movef(c, v.n[VX], v.n[VY], v.n[VZ] );
-}
-
-void
-c3cam_move_by_eye(
- c3cam_p c,
- const c3vec3 new_eye)
-{
- c3vec3 diff = c3vec3_sub(new_eye, c->eye);
-
- c->lookat = c3vec3_add(c->lookat, diff);
- c->eye = c3vec3_add(c->eye, diff);
-
- c3cam_update(c);
-}
-
-void
-c3cam_move_by_lookat(
- c3cam_p c,
- const c3vec3 new_lookat)
-{
- c3vec3 diff = c3vec3_sub(new_lookat, c->lookat);
-
- c->lookat = c3vec3_add(c->lookat, diff);
- c->eye = c3vec3_add(c->eye, diff);
-
- c3cam_update(c);
-}
-
-void
-c3cam_move_abs(
- c3cam_p c,
- const c3vec3 v)
-{
- c->lookat = c3vec3_add(c->lookat, v);
- c->eye = c3vec3_add(c->eye, v);
-
- c3cam_update(c);
-}
-
-void
-c3cam_rot_about_eye(
- c3cam_p c,
- const c3mat4p rot)
-{
- c3vec3 view = c3vec3_sub(c->lookat, c->eye);
-
- view = c3mat4_mulv3(rot, view);
- c->up = c3mat4_mulv3(rot, c->up);
-
- c->lookat = c3vec3_add(c->eye, view);
-
- c3cam_update(c);
-}
-
-void
-c3cam_rot_about_lookat(
- c3cam_p c,
- const c3mat4p rot)
-{
- // NOT QUITE RIGHT YET
-
- c3vec3 view = c3vec3_sub(c->eye, c->lookat);
-
- view = c3mat4_mulv3(rot, view);
- c->up = c3mat4_mulv3(rot, c->up);
-
- c->eye = c3vec3_add(c->lookat, view);
-
- c3cam_update(c);
-}
-
-void
-c3cam_update_matrix(
- c3cam_p c)
-{
- c3cam_update(c);
-
- c3mat4 m1 = translation3D(c3vec3_minus(c->eye));
- c3mat4 m2 = c3mat4_vec4(
- c3vec4f(c->side.n[VX], c->up.n[VX], c->forward.n[VX], 0.0),
- c3vec4f(c->side.n[VY], c->up.n[VY], c->forward.n[VY], 0.0),
- c3vec4f(c->side.n[VZ], c->up.n[VZ], c->forward.n[VZ], 0.0),
- c3vec4f(0.0, 0.0, 0.0, 1.0));
- c->mtx = c3mat4_mul(&m1, &m2);
-}
-
-void
-c3cam_reset(
- c3cam_p c)
-{
- memset(c, 0, sizeof(*c));
- c->up = c3vec3f( 0.0, 1.0, 0.0 );
- c->eye = c3vec3f(0.0, 0.0, 10.0);
- c->lookat = c3vec3f(0.0,0.0,0.0);
- c->fov = 50.0f;
- c->mtx = identity3D();
-
- c3cam_update(c);
-}
-
-c3cam_p
-c3cam_new()
-{
- c3cam_p c = malloc(sizeof(*c));
- memset(c, 0, sizeof(*c));
- c3cam_reset(c);
- return c;
-}
-
-void
-c3cam_init(
- c3cam_p c)
-{
- memset(c, 0, sizeof(*c));
- c3cam_reset(c);
-}
-
-void
-c3cam_update(
- c3cam_p c)
-{
- /* get proper side and forward vectors, and distance */
- c->forward = c3vec3_minus(c3vec3_sub(c->lookat, c->eye));
- c->distance = c3vec3_length(c->forward);
- c->forward = c3vec3_divf(c->forward, c->distance);
-
- c->side = c3vec3_cross(c->up, c->forward);
- c->up = c3vec3_cross(c->forward, c->side);
-
- c->forward = c3vec3_normalize(c->forward);
- c->up = c3vec3_normalize(c->up);
- c->side = c3vec3_normalize(c->side);
-}
+++ /dev/null
-/*
- c3camera.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
- Copyright (c) 1998 Paul Rademacher
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __C3VIEW_H___
-#define __C3VIEW_H___
-
-#include "c3algebra.h"
-
-typedef struct c3cam_t {
- c3vec3 eye, lookat;
- c3vec3 up, side, forward;
- c3mat4 mtx;
- c3f distance;
- c3f fov;
-} c3cam_t, *c3cam_p;
-
-/******************************* set_distance() ***********/
-/* This readjusts the distance from the eye to the lookat */
-/* (changing the eye point in the process) */
-/* The lookat point is unaffected */
-void
-c3cam_set_distance(
- c3cam_p c,
- const c3f new_distance);
-
-/******************************* set_up() ***************/
-void
-c3cam_set_upv(
- c3cam_p c,
- const c3vec3 new_up);
-void
-c3cam_set_upf(
- c3cam_p c,
- const c3f x,
- const c3f y,
- const c3f z);
-
-/******************************* set_eye() ***************/
-void
-c3cam_set_eyev(
- c3cam_p c,
- const c3vec3 new_eye);
-void
-c3cam_set_eyef(
- c3cam_p c,
- const c3f x,
- const c3f y,
- const c3f z);
-
-/******************************* set_lookat() ***************/
-void
-c3cam_set_lookatv(
- c3cam_p c,
- const c3vec3 new_lookat);
-void
-c3cam_set_lookatf(
- c3cam_p c,
- const c3f x,
- const c3f y,
- const c3f z);
-
-/******************************* roll() *****************/
-/* Rotates about the forward vector */
-/* eye and lookat remain unchanged */
-void
-c3cam_roll(
- c3cam_p c,
- const c3f angle);
-
-/******************************* eye_yaw() *********************/
-/* Rotates the eye about the lookat point, using the up vector */
-/* Lookat is unaffected */
-void
-c3cam_eye_yaw(
- c3cam_p c,
- const c3f angle);
-
-/******************************* eye_yaw_abs() ******************/
-/* Rotates the eye about the lookat point, with a specific axis */
-/* Lookat is unaffected */
-void
-c3cam_eye_yaw_abs(
- c3cam_p c,
- const c3f angle,
- const c3vec3 axis);
-
-/******************************* eye_pitch() ************/
-/* Rotates the eye about the side vector */
-/* Lookat is unaffected */
-void
-c3cam_eye_pitch(
- c3cam_p c,
- const c3f angle);
-
-/******************************* lookat_yaw()************/
-/* This assumes the up vector is correct. */
-/* Rotates the lookat about the side vector */
-/* Eye point is unaffected */
-void
-c3cam_lookat_yaw(
- c3cam_p c,
- const c3f angle);
-
-/******************************* lookat_pitch() *********/
-/* Rotates the lookat point about the side vector */
-/* This assumes the side vector is correct. */
-/* Eye point is unaffected */
-void
-c3cam_lookat_pitch(
- c3cam_p c,
- const c3f angle);
-
-/******************************* reset_up() ******************/
-/* Resets the up vector to a specified axis (0=X, 1=Y, 2=Z) */
-/* Also sets the eye point level with the lookat point, */
-/* along the specified axis */
-void
-c3cam_reset_up_axis(
- c3cam_p c,
- const int axis_num);
-void
-c3cam_reset_up(
- c3cam_p c);
-
-/******************************* move() ********************/
-/* Moves a specified distance in the forward, side, and up */
-/* directions. This function does NOT move by world */
-/* coordinates. To move by world coords, use the move_abs */
-/* function. */
-void
-c3cam_movef(
- c3cam_p c,
- const c3f side_move,
- const c3f up_move,
- const c3f forw_move);
-void
-c3cam_movev(
- c3cam_p c,
- const c3vec3 v); /* A vector version of the above command */
-
-/******************************* move_by_eye() ***********/
-/* Sets the eye point, AND moves the lookat point by the */
-/* same amount as the eye is moved. */
-void
-c3cam_move_by_eye(
- c3cam_p c,
- const c3vec3 new_eye);
-
-/******************************* move_by_lookat() *********/
-/* Sets the lookat point, AND moves the eye point by the */
-/* same amount as the lookat is moved. */
-void
-c3cam_move_by_lookat(
- c3cam_p c,
- const c3vec3 new_lookat);
-
-/******************************* move_abs() *****************/
-/* Move the eye and lookat in world coordinates */
-void
-c3cam_move_abs(
- c3cam_p c,
- const c3vec3 v);
-
-/****************************** rot_about_eye() ************/
-/* Rotates the lookat point about the eye, based on a 4x4 */
-/* (pure) rotation matrix */
-void
-c3cam_rot_about_eye(
- c3cam_p c,
- const c3mat4p rot);
-
-/****************************** rot_about_lookat() ************/
-/* Rotates the lookat point about the lookat, based on a 4x4 */
-/* (pure) rotation matrix */
-void
-c3cam_rot_about_lookat(
- c3cam_p c,
- const c3mat4p rot);
-
-/******************************* make_mtx() *************/
-/* Constructs a 4x4 matrix - used by load_to_openGL() */
-void
-c3cam_update_matrix(
- c3cam_p c);
-
-/******************************* load_to_openGL() ********/
-/* Sets the OpenGL modelview matrix based on the current */
-/* camera coordinates */
-//void c3cam_load_to_openGL();
-
-/******************************* load_to_openGL_noident() ******/
-/* Multiplies the current camera matrix by the existing openGL */
-/* modelview matrix. This is same as above function, but */
-/* does not set the OpenGL matrix to identity first */
-//void c3cam_load_to_openGL_noident();
-
-/******************************* reset() ****************/
-/* Resets the parameters of this class */
-void
-c3cam_reset(
- c3cam_p c);
-
-/******************************* c3cam_t() ************/
-/* Constructor */
-c3cam_p
-c3cam_new();
-
-void
-c3cam_init(
- c3cam_p c);
-/******************************* update() ****************/
-/* updates the view params. Call this after making */
-/* direct changes to the vectors or points of this class */
-void c3cam_update(
- c3cam_p c);
-
-#endif /* __C3VIEW_H___ */
+++ /dev/null
-#ifndef __C3_CONFIG__
-#define __C3_CONFIG__
-#define CONFIG_C3_VERSION "0.1.0"
-#define CONFIG_C3_PLATFORM "darwin"
-// #define CONFIG_C3_CAIRO 1
-#endif
+++ /dev/null
-#ifndef __C3_CONFIG__
-#define __C3_CONFIG__
-#define CONFIG_C3_VERSION "0.1.1"
-#define CONFIG_C3_PLATFORM "linux"
-#define CONFIG_C3_CAIRO 1
-#endif
+++ /dev/null
-/*
- c3config.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __C3_CONFIG_MAIN_H_
-#define __C3_CONFIG_MAIN_H_
-
-#if __APPLE__
-#include "c3config-darwin.h"
-#elif __linux__
-#include "c3config-linux.h"
-#else
-#error No target platform detected, tweak the makefile
-#endif
-
-#endif // __C3_CONFIG_MAIN_H_
+++ /dev/null
-/*
- c3context.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include "c3context.h"
-#include "c3object.h"
-#include "c3light.h"
-#include "c3driver_context.h"
-
-c3context_p
-c3context_new(
- int w,
- int h)
-{
- c3context_p res = malloc(sizeof(*res));
- return c3context_init(res, w, h);
-}
-
-c3context_p
-c3context_init(
- c3context_p c,
- int w,
- int h)
-{
- memset(c, 0, sizeof(*c));
-
- c3context_view_t v = {
- .type = C3_CONTEXT_VIEW_EYE,
- .size = c3vec2f(w, h),
- .dirty = 1,
- .index = c->views.count,
- };
- c3cam_init(&v.cam);
- c3context_view_array_add(&c->views, v);
- c->root = c3object_new(NULL);
- c->root->context = c;
-
- return c;
-}
-
-void
-c3context_dispose(
- c3context_p c)
-{
- c3object_dispose(c->root);
- for (int i = 0; i < c->views.count; i++)
- c3geometry_array_free(&c->views.e[i].projected);
- free(c);
-}
-
-static c3context_view_p qsort_view;
-
-/*
- * Computes the distance from the 'eye' of the camera, sort by this value
- */
-static int
-_c3_z_sorter(
- const void *_p1,
- const void *_p2)
-{
- c3geometry_p g1 = *(c3geometry_p*)_p1;
- c3geometry_p g2 = *(c3geometry_p*)_p2;
- // get center of bboxes
- c3vec3 c1 = c3vec3_add(g1->bbox.min, c3vec3_divf(c3vec3_sub(g1->bbox.max, g1->bbox.min), 2));
- c3vec3 c2 = c3vec3_add(g2->bbox.min, c3vec3_divf(c3vec3_sub(g2->bbox.max, g2->bbox.min), 2));
-
- c3cam_p cam = &qsort_view->cam;
- c3f d1 = c3vec3_length2(c3vec3_sub(c1, cam->eye));
- c3f d2 = c3vec3_length2(c3vec3_sub(c2, cam->eye));
-
- if (d1 > qsort_view->z.max) qsort_view->z.max = d1;
- if (d1 < qsort_view->z.min) qsort_view->z.min = d1;
- if (d2 > qsort_view->z.max) qsort_view->z.max = d2;
- if (d2 < qsort_view->z.min) qsort_view->z.min = d2;
- /*
- * make sure transparent items are drawn after everyone else
- */
- if (g1->mat.color.n[3] < 1)
- d1 -= 100000.0;
- if (g2->mat.color.n[3] < 1)
- d2 -= 100000.0;
- if (g1->type.type == C3_LIGHT_TYPE)
- d1 = -200000 + (int)(((c3light_p)g1)->light_id);
- if (g2->type.type == C3_LIGHT_TYPE)
- d2 = -200000 + (int)(((c3light_p)g2)->light_id);
-
- return d1 < d2 ? 1 : d1 > d2 ? -1 : 0;
-}
-
-int
-c3context_project(
- c3context_p c)
-{
- if (!c->root)
- return 0;
- int res = 0;
- /*
- * if the root object is dirty, all the views are also
- * dirty since the geometry has changed
- */
- if (c->root->dirty) {
- for (int ci = 0; ci < c->views.count; ci++)
- c->views.e[ci].dirty = 1;
- c3mat4 m = identity3D();
- c3object_project(c->root, &m);
- res++;
- }
-
- /*
- * if the current view is dirty, gather all the geometry
- * and Z sort it in a basic way
- */
- c3context_view_p v = qsort_view = c3context_view_get(c);
- if (v->dirty) {
- res++;
- c3cam_update_matrix(&v->cam);
-
- c3geometry_array_p array = &c3context_view_get(c)->projected;
- c3geometry_array_clear(array);
- c3object_get_geometry(c->root, array);
-
- v->z.min = 1000000000;
- v->z.max = -1000000000;
-
- qsort(v->projected.e,
- v->projected.count, sizeof(v->projected.e[0]),
- _c3_z_sorter);
- v->z.min = sqrt(v->z.min) * 0.5f;
- v->z.max = sqrt(v->z.max);
-
- /*
- * Recalculate the perspective view using the new Z values
- */
- v->projection = perspective3D(
- v->cam.fov,
- v->size.x / v->size.y,
- v->z.min, v->z.max);
-
- v->dirty = 0;
- }
- return res;
-}
-
-void
-c3context_draw(
- c3context_p c)
-{
- c3context_project(c);
-
- c3context_view_p v = c3context_view_get(c);
-
- C3_DRIVER(c, context_view_draw, v);
-
- c3geometry_array_p array = &v->projected;
- for (int gi = 0; gi < array->count; gi++) {
- c3geometry_p g = array->e[gi];
- c3geometry_draw(g);
- }
-}
-
+++ /dev/null
-/*
- c3context.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3CONTEXT_H___
-#define __C3CONTEXT_H___
-
-#include "c3algebra.h"
-#include "c3geometry.h"
-#include "c3pixels.h"
-#include "c3program.h"
-#include "c3camera.h"
-
-enum {
- C3_CONTEXT_VIEW_NONE = 0,
- C3_CONTEXT_VIEW_EYE,
- C3_CONTEXT_VIEW_LIGHT
-};
-
-typedef struct c3context_view_t {
- int type : 4, // C3_CONTEXT_VIEW_EYE...
- dirty : 1,
- index : 4; // index in context array
- c3apiobject_t bid; // buffer id (fbo, texture...)
- c3vec2 size; // in pixels. for fbo/textures/window
- c3cam_t cam;
- c3mat4 projection; // projection matrix
-
- c3geometry_array_t projected;
- struct {
- c3f min, max;
- } z;
-} c3context_view_t, *c3context_view_p;
-
-DECLARE_C_ARRAY(c3context_view_t, c3context_view_array, 4);
-
-//! c3context_t is a container for a 'scene' to be drawn
-/*!
- * A c3context_t holds a root object, a list of already cached projected
- * version of the geometry, and a driver that can be customized to draw it.
- *
- * This is a wrapper around a "top level object", the list of projected
- * geometries is kept, purged and resorted if the root object becomes
- * dirty
- */
-typedef struct c3context_t {
- int current;
- c3context_view_array_t views;
-
- struct c3object_t * root; // root object
-
- c3pixels_array_t pixels; // pixels, textures...
- c3program_array_t programs; // fragment, vertex, geometry shaders
-
- const struct c3driver_context_t ** driver;
-} c3context_t, *c3context_p;
-
-//! Allocates a new context of size w=width, h=height
-c3context_p
-c3context_new(
- int w,
- int h);
-
-//! Initializes a new context 'c' of size w=width, h=height
-c3context_p
-c3context_init(
- c3context_p c,
- int w,
- int h);
-
-//! Disposes the context, and everything underneath
-void
-c3context_dispose(
- c3context_p c);
-
-//! Reproject geometry for dirty objects
-int
-c3context_project(
- c3context_p c);
-//! Draws the context
-void
-c3context_draw(
- c3context_p c);
-
-IMPLEMENT_C_ARRAY(c3context_view_array);
-
-/*
- * Set and get the current view, this is done
- * before projecting and drawing
- */
-static inline c3context_view_p
-c3context_view_get(
- c3context_p c )
-{
- return &c->views.e[c->current];
-}
-
-static inline c3context_view_p
-c3context_view_get_at(
- c3context_p c,
- int view)
-{
- if (view < c->views.count)
- return &c->views.e[view];
- return NULL;
-}
-
-static inline void
-c3context_view_set(
- c3context_p c,
- int view)
-{
- if (view < c->views.count)
- c->current = view;
-}
-
-#endif /* __C3CONTEXT_H___ */
+++ /dev/null
-/*
- c3driver.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3DRIVER_H___
-#define __C3DRIVER_H___
-
-#define C3_DRIVER_CALL(__o, __callback, __args...) { \
- if ((__o) && (__o)->driver) \
- for (int _di = 0; (__o)->driver[_di]; _di++) \
- if ((__o)->driver[_di]->__callback) { \
- (__o)->driver[_di]->__callback(__o, (__o)->driver[_di], ##__args); \
- break; \
- } \
- }
-#define C3_DRIVER(__o, __callback, __args...) \
- C3_DRIVER_CALL(__o, __callback, ##__args)
-#define C3_DRIVER_INHERITED(__o, __driver, __callback, __args...) { \
- if ((__o) && (__o)->driver) \
- for (int _di = 0; (__o)->driver[_di]; _di++) \
- if ((__o)->driver[_di] == __driver && (__o)->driver[_di+1]) { \
- (__o)->driver[_di+1]->__callback(__o, (__o)->driver[_di+1], ##__args); \
- break; \
- } \
- }
-#endif /* __C3DRIVER_H___ */
+++ /dev/null
-/*
- c3driver_context.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3DRIVER_CONTEXT_H___
-#define __C3DRIVER_CONTEXT_H___
-
-#include "c3driver.h"
-
-struct c3context_t;
-struct c3driver_context_t;
-struct c3geometry_t;
-struct c3context_view_t;
-
-typedef struct c3driver_context_t {
- /*
- * Called when a geometry projection had changed in world view
- * can also be used to prepare resources like textures and so on
- */
- void (*geometry_project)(
- struct c3context_t * c,
- const struct c3driver_context_t *d,
- struct c3geometry_t * g,
- union c3mat4 * mat);
- /*
- * Called to draw a geometry
- */
- void (*geometry_draw)(
- struct c3context_t * c,
- const struct c3driver_context_t *d,
- struct c3geometry_t * g);
-
- /*
- * Called when starting to draw a context view(point)
- */
- void (*context_view_draw)(
- struct c3context_t * c,
- const struct c3driver_context_t *d,
- struct c3context_view_t * ctx);
-
- /*
- * called when a geometry is disposed of, let the application
- * delete resources like textures etc
- */
- void (*geometry_dispose)(
- struct c3context_t * c,
- const struct c3driver_context_t *d,
- struct c3geometry_t * g);
-} c3driver_context_t, *c3driver_context_p;
-
-#endif /* __C3DRIVER_CONTEXT_H___ */
+++ /dev/null
-/*
- c3driver_geometry.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3DRIVER_GEOMETRY_H___
-#define __C3DRIVER_GEOMETRY_H___
-
-#include "c3driver.h"
-
-struct c3geometry_t;
-
-typedef struct c3driver_geometry_t {
- void (*dispose)(
- struct c3geometry_t * geometry,
- const struct c3driver_geometry_t *d);
- void (*project)(
- struct c3geometry_t * geometry,
- const struct c3driver_geometry_t *d,
- union c3mat4 * mat);
- void (*draw)(
- struct c3geometry_t * geometry,
- const struct c3driver_geometry_t *d);
-} c3driver_geometry_t, *c3driver_geometry_p;
-
-
-#endif /* __C3DRIVER_GEOMETRY_H___ */
+++ /dev/null
-/*
- c3driver_object.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3DRIVER_OBJECT_H___
-#define __C3DRIVER_OBJECT_H___
-
-#include "c3driver.h"
-
-struct c3object_t;
-struct c3geometry_array_t;
-union c3mat4;
-
-typedef struct c3driver_object_t {
- /*
- * Delete any object related to this object, geometry etc
- * The object will still exist, just empty
- */
- void (*clear)(
- struct c3object_t * object,
- const struct c3driver_object_t * d);
- /*
- * Dispose of the remaining memory for an object, detaches it
- * and frees remaining traces of it
- */
- void (*dispose)(
- struct c3object_t * object,
- const struct c3driver_object_t * d);
- /*
- * Adds sub objects geometry and self geometry to array 'out'
- */
- void (*get_geometry)(
- struct c3object_t * object,
- const struct c3driver_object_t * d,
- struct c3geometry_array_t * out);
- /*
- * Reproject geometry along matrix 'mat', applies our own
- * transform and call down the chain for sub-objects
- */
- void (*project)(
- struct c3object_t * object,
- const struct c3driver_object_t * d,
- union c3mat4 * mat);
-} c3driver_object_t, *c3driver_object_p;
-
-
-#endif /* __C3DRIVER_OBJECT_H___ */
+++ /dev/null
-/*
- c3geometry.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include <stdio.h>
-#include <math.h>
-#include "c3object.h"
-#include "c3context.h"
-#include "c3driver_geometry.h"
-#include "c3driver_context.h"
-
-static void
-_c3geometry_dispose(
- c3geometry_p g,
- const struct c3driver_geometry_t *d)
-{
- /*
- * If we're still attached to an object, detach
- */
- if (g->object) {
- for (int oi = 0; oi < g->object->geometry.count; oi++)
- if (g->object->geometry.e[oi] == g) {
- c3geometry_array_delete(&g->object->geometry, oi, 1);
- c3object_set_dirty(g->object, true);
- break;
- }
- g->object = NULL;
- }
- /* let the context driver have a chance to clear it's own stuff */
- if (g->object && g->object->context)
- C3_DRIVER(g->object->context, geometry_dispose, g);
- str_free(g->name);
- c3vertex_array_free(&g->vertice);
- c3tex_array_free(&g->textures);
- c3colorf_array_free(&g->colorf);
- free(g);
-// C3_DRIVER_INHERITED(g, d, dispose);
-}
-
-static void
-_c3geometry_project(
- c3geometry_p g,
- const struct c3driver_geometry_t *d,
- c3mat4p m)
-{
- /* make sure there are actual elements in the array
- * if it had been purged, the element count might remain
- * but the array size is zero
- */
- if (g->vertice.count < g->vertice.size) {
- for (int vi = 0; vi < g->vertice.count; vi++) {
- c3vec3 v = c3mat4_mulv3(m, g->vertice.e[vi]);
- if (vi == 0)
- g->bbox.min = g->bbox.max = v;
- else {
- g->bbox.max = c3vec3_min(g->bbox.min, v);
- g->bbox.max = c3vec3_max(g->bbox.max, v);
- }
- }
- }
- /* else -- do not clear bbox on purged arrays
- g->bbox.min = g->bbox.max = c3vec3f(0,0,0); */
-
- if (g->object && g->object->context)
- C3_DRIVER(g->object->context, geometry_project, g, m);
- g->dirty = 0;
-// C3_DRIVER_INHERITED(g, d, project);
-}
-
-static void
-_c3geometry_draw(
- c3geometry_p g,
- const struct c3driver_geometry_t *d)
-{
- if (g->object && g->object->context)
- C3_DRIVER(g->object->context, geometry_draw, g);
-// C3_DRIVER_INHERITED(g, d, draw);
-}
-
-const c3driver_geometry_t c3geometry_driver = {
- .dispose = _c3geometry_dispose,
- .project = _c3geometry_project,
- .draw = _c3geometry_draw,
-};
-
-c3geometry_p
-c3geometry_new(
- c3geometry_type_t type,
- c3object_p o /* = NULL */)
-{
- c3geometry_p res = malloc(sizeof(c3geometry_t));
- return c3geometry_init(res, type, o);
-}
-
-c3geometry_p
-c3geometry_init(
- c3geometry_p g,
- c3geometry_type_t type,
- struct c3object_t * o /* = NULL */)
-{
- memset(g, 0, sizeof(*g));
- static const c3driver_geometry_t * list[] = {
- &c3geometry_driver, NULL,
- };
- g->driver = list;
- g->type = type;
- g->dirty = 1;
- if (o)
- c3object_add_geometry(o, g);
- return g;
-}
-
-c3driver_geometry_p
-c3geometry_get_custom(
- c3geometry_p g )
-{
- if (g->custom)
- return (c3driver_geometry_p)g->driver[0];
- int cnt = 0;
- for (int di = 0; g->driver[di]; di++)
- cnt++;
- c3driver_geometry_p * newd = malloc(sizeof(c3driver_geometry_p) * (cnt + 2));
- memcpy(&newd[1], g->driver, (cnt + 1) * sizeof(c3driver_geometry_p));
- newd[0] = malloc(sizeof(c3driver_geometry_t));
- memset(newd[0], 0, sizeof(c3driver_geometry_t));
- g->custom = 1;
- g->driver = (typeof(g->driver))newd;
- return newd[0];
-}
-
-void
-c3geometry_dispose(
- c3geometry_p g)
-{
- C3_DRIVER(g, dispose);
-}
-
-void
-c3geometry_project(
- c3geometry_p g,
- c3mat4p m)
-{
- if (!g->dirty)
- return;
- C3_DRIVER(g, project, m);
-}
-
-void
-c3geometry_draw(
- c3geometry_p g )
-{
- C3_DRIVER(g, draw);
-}
-
-void
-c3geometry_factor(
- c3geometry_p g,
- c3f tolerance,
- c3f normaltolerance)
-{
- printf("%s has %d/%d/%d vertices/normals/tex and %d indexes\n", __func__,
- g->vertice.count, g->normals.count, g->textures.count,
- g->indices.count);
-
- c3f tolerance2 = tolerance * tolerance;
-
- int in_index = g->indices.count;
- int vcount = in_index ? in_index : g->vertice.count;
- int input = 0;
- int output = 0;
- g->indices.count = 0;
- while (input < vcount) {
- int current = in_index ? g->indices.e[input] : input;
- c3vec3 v = g->vertice.e[current];
- c3vec3 n = g->normals.count ? g->normals.e[current] : c3vec3f(0,0,0);
- c3vec3 np = c3vec3_polar(n); // normal in polar coord
-
- int oi = -1;
- for (int ci = 0; ci < output && oi == -1; ci++)
- if (c3vec3_length2(c3vec3_sub(g->vertice.e[ci], v)) < tolerance2) {
- if (g->normals.count) {
- c3vec3 nc = g->normals.e[ci];
- c3vec3 pc = c3vec3_polar(nc);
-
- c3vec3 d = c3vec3_sub(np, pc);
- while (d.n[0] <= -M_PI) d.n[0] += (2*M_PI);
- while (d.n[1] <= -M_PI) d.n[1] += (2*M_PI);
-
- if (fabs(d.n[0]) < normaltolerance &&
- fabs(d.n[1]) < normaltolerance) {
- oi = ci;
- // replace the compared normal with the 'merged' one
- // that should hopefully trim it to the right direction
- // somehow. Not perfect obviously
- g->normals.e[ci] = c3vec3_add(n, nc);
- }
- } else
- oi = ci;
- }
- if (oi == -1) {
- oi = output;
- g->vertice.e[output] = g->vertice.e[current];
- if (g->textures.count)
- g->textures.e[output] = g->textures.e[current];
- if (g->normals.count)
- g->normals.e[output] = n;
- if (g->colorf.count)
- g->colorf.e[output] = g->colorf.e[current];
- output++;
- }
- c3indices_array_add(&g->indices, oi);
- input++;
- }
- g->vertice.count = output;
- c3vertex_array_realloc(&g->vertice, output);
- if (g->textures.count) {
- g->textures.count = output;
- c3tex_array_realloc(&g->textures, output);
- }
- if (g->normals.count) {
- g->normals.count = output;
- c3vertex_array_realloc(&g->normals, output);
- for (int ni = 0; ni < output; ni++)
- g->normals.e[ni] = c3vec3_normalize(g->normals.e[ni]);
- }
- if (g->colorf.count) {
- g->colorf.count = output;
- c3colorf_array_realloc(&g->colorf, output);
- }
- c3geometry_set_dirty(g, 1);
-
- printf("%s converted to %d vertices and %d indexes\n", __func__,
- g->vertice.count, g->indices.count);
-}
-
-void
-c3geometry_set_dirty(
- c3geometry_p g,
- int dirty )
-{
- g->dirty = dirty;
- if (dirty && g->object)
- c3object_set_dirty(g->object, 1);
-}
+++ /dev/null
-/*
- c3geometry.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * c3geometry is a structure containing one set of vertices and various
- * bits related to it. Ultimately it contains a pre-cached projected
- * version of the vertices that the drawing code can use directly.
- * c3geometry is aways attached to a c3object as a parent.
- */
-
-#ifndef __C3GEOMETRY_H___
-#define __C3GEOMETRY_H___
-
-#include "c3types.h"
-#include "c_utils.h"
-
-
-struct c3object_t;
-struct c3pixels_t;
-struct c3program_t;
-
-/*
- * Allow per-array storage of an extra buffer object
- * if 'mutable' is not set (default), the array can be clear()ed after
- * the buffer is bound.
- * If the array is mutable, setting the 'dirty' flag will signal
- * the rendering layer that it needs to update the buffer object
- */
-typedef struct c3geometry_buffer_t {
- c3apiobject_t bid; // buffer object
- void * refCon; // reference constant for application use
- int mutable : 1, dirty : 1;
-} c3geometry_buffer_t, * c3geometry_buffer_p;
-
-DECLARE_C_ARRAY(c3vertex_t, c3vertex_array, 16, c3geometry_buffer_t buffer);
-DECLARE_C_ARRAY(c3tex_t, c3tex_array, 16, c3geometry_buffer_t buffer);
-DECLARE_C_ARRAY(c3colorf_t, c3colorf_array, 16, c3geometry_buffer_t buffer);
-DECLARE_C_ARRAY(c3index_t, c3indices_array, 16, c3geometry_buffer_t buffer);
-
-//! Geometry material.
-typedef struct c3material_t {
- c3colorf_t color;
- struct c3pixels_t * texture;
- struct c3program_t * program;
- struct {
- uint32_t src, dst;
- } blend;
-} c3material_t;
-
-#define C3_TYPE(_a,_b,_c,_d) \
- (((uint32_t)(_a)<<24)|((uint32_t)(_b)<<16)|((uint32_t)(_c)<<8)|(_d))
-
-//! Generic geometry type
-enum {
- C3_RAW_TYPE = C3_TYPE('r','a','w','g'),
- C3_TRIANGLE_TYPE = C3_TYPE('t','r','i','a'),
-};
-
-/*!
- * geometry type.
- * The type is used as non-opengl description of what the geometry
- * contains, like "texture", and the subtype can be used to store the
- * real format of the vertices. like GL_LINES etc
- */
-typedef struct c3geometry_type_t {
- uint32_t type; // C3_RAW_TYPE etc
- c3apiobject_t subtype; // GL_LINES etc
-} c3geometry_type_t;
-
-/*!
- * Geometry object. Describes a set of vertices, texture coordinates,
- * normals, colors and material
- * The projection is not set here, a geometry is always attached to a
- * c3object that has the projection
- */
-typedef struct c3geometry_t {
- c3geometry_type_t type; // geometry type
- int dirty : 1,
- custom : 1, // has a custom driver
- hidden : 8; // hidden from context_view, bitfield
- str_p name; // optional
- c3apiobject_t bid; // buffer id for opengl
-
- c3material_t mat;
- struct c3object_t * object; // parent object
- const struct c3driver_geometry_t ** driver;
-
- c3bbox_t bbox; // world aligned bounding box
- c3vertex_array_t vertice;
- c3tex_array_t textures; // optional: texture coordinates
- c3vertex_array_t normals; // optional: vertex normals
- c3indices_array_t indices; // optional: vertex indices
- // could go ?
- c3colorf_array_t colorf; // optional: vertex colors
-
- /*
- * Some shared attributes
- */
- union {
- struct {
- float width;
- } line;
- };
-} c3geometry_t, *c3geometry_p;
-
-DECLARE_C_ARRAY(c3geometry_p, c3geometry_array, 4);
-
-//! Allocates a new geometry, init it, and attached it to parent 'o' (optional)
-c3geometry_p
-c3geometry_new(
- c3geometry_type_t type,
- struct c3object_t * o /* = NULL */);
-//! Init an existing new geometry, and attached it to parent 'o' (optional)
-c3geometry_p
-c3geometry_init(
- c3geometry_p g,
- c3geometry_type_t type,
- struct c3object_t * o /* = NULL */);
-//! Disposes (via the driver interface) the geometry
-void
-c3geometry_dispose(
- c3geometry_p g);
-
-//! Prepares a geometry.
-/*!
- * The project phase is called only when the container object is 'dirty'
- * for example if it's projection has changed.
- * The project call is responsible for reprojecting the geometry and that
- * sort of things
- */
-void
-c3geometry_project(
- c3geometry_p g,
- c3mat4p m);
-
-//! Draw the geometry
-/*
- * Called when drawing the context. Typicaly this calls the geometry
- * driver, which in turn will call the 'context' draw method, and the
- * application to draw this particular geometry
- */
-void
-c3geometry_draw(
- c3geometry_p g );
-
-//! Sets or clear geometry dirty bit
-/*
- * This will dirty parent objects if set to 1
- */
-void
-c3geometry_set_dirty(
- c3geometry_p g,
- int dirty );
-
-/*
- * if not present, create an index array, and collapses
- * the vertex array by removing vertices that are within
- * 'tolerance' (as a distance between vertices considered equals).
- * If the normals exists, they are also compared
- * to normaltolerance (in radian) and if both position and normals
- * are within tolerance, the vertices are collapsed and the normals
- * are averaged.
- * This code allows smooth rendering of STL files generated by
- * CAD programs that generate only triangle normals.
- */
-void
-c3geometry_factor(
- c3geometry_p g,
- c3f tolerance,
- c3f normaltolerance);
-
-//! allocate (if not there) and return a custom driver for this geometry
-/*!
- * Geometries come with a default, read only driver stack.. It is a constant
- * global to save memory for each of the 'generic' object.
- * This call will duplicate that stack and allocate (if not there) a read/write
- * empty driver that the application can use to put their own, per object,
- * callback. For example you can add your own project() or draw() function
- * and have it called first
- */
-struct c3driver_geometry_t *
-c3geometry_get_custom(
- c3geometry_p g );
-
-IMPLEMENT_C_ARRAY(c3geometry_array);
-IMPLEMENT_C_ARRAY(c3vertex_array);
-IMPLEMENT_C_ARRAY(c3tex_array);
-IMPLEMENT_C_ARRAY(c3colorf_array);
-IMPLEMENT_C_ARRAY(c3indices_array);
-
-static inline c3geometry_type_t
-c3geometry_type(uint32_t type, int subtype)
-{
- c3geometry_type_t r;// = { .type = type, .subtype = subtype }; // older gcc <4.6 doesn't like this
- r.type = type; r.subtype = (c3apiobject_t)subtype;
- return r;
-}
-
-#endif /* __C3GEOMETRY_H___ */
+++ /dev/null
-/*
- c3light.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- simavr is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- simavr 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 simavr. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include <stdio.h>
-#include <string.h>
-#include "c3light.h"
-
-c3light_p
-c3light_new(
- struct c3object_t * o /* = NULL */)
-{
- c3light_p res = malloc(sizeof(*res));
- return c3light_init(res, o);
-}
-
-c3light_p
-c3light_init(
- c3light_p l,
- struct c3object_t * o /* = NULL */)
-{
- memset(l, 0, sizeof(*l));
- c3geometry_init(&l->geometry,
- c3geometry_type(C3_LIGHT_TYPE, 0),
- o);
-
- return l;
-}
+++ /dev/null
-/*
- c3light.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- simavr is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- simavr 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 simavr. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3LIGHT_H___
-#define __C3LIGHT_H___
-
-#include "c3geometry.h"
-
-enum {
- C3_LIGHT_TYPE = C3_TYPE('l','i','g','h'),
-};
-
-typedef struct c3light_t {
- c3geometry_t geometry;
- c3apiobject_t light_id;
- int context_view_index;
- c3vec4 position;
- c3vec3 direction;
- c3f fov;
- struct {
- c3colorf_t ambiant;
- c3colorf_t specular;
- } color;
-} c3light_t, *c3light_p;
-
-c3light_p
-c3light_new(
- struct c3object_t * o /* = NULL */);
-
-c3light_p
-c3light_init(
- c3light_p l,
- struct c3object_t * o /* = NULL */);
-
-#endif /* __C3LIGHT_H___ */
+++ /dev/null
-/*
- c3lines.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3object.h"
-#include "c3context.h"
-#include "c3driver_geometry.h"
-#include "c3lines.h"
-
-
-void
-c3lines_prepare(
- c3vertex_p vertices, // points A,B pairs
- size_t count,
- c3vertex_array_p v, // triangles
- c3tex_array_p tex,
- c3f lineWidth,
- c3mat4p m)
-{
- c3tex_array_clear(tex);
- c3vertex_array_clear(v);
- for (int l = 0; l < count; l += 2) {
- c3vec3 a = c3mat4_mulv3(m, vertices[l]);
- c3vec3 b = c3mat4_mulv3(m, vertices[l+1]);
-
- c3vec3 e = c3vec3_mulf(c3vec3_normalize(c3vec3_sub(b, a)), lineWidth);
-
- c3vec3 N = c3vec3f(-e.y, e.x, 0);
- c3vec3 S = c3vec3_minus(N);
- c3vec3 NE = c3vec3_add(N, e);
- c3vec3 NW = c3vec3_sub(N, e);
- c3vec3 SW = c3vec3_minus(NE);
- c3vec3 SE = c3vec3_minus(NW);
-#if 0
- c3vertex_array_add(v, c3vec3_add(a, SW));
- c3vertex_array_add(v, c3vec3_add(a, NW));
- c3vertex_array_add(v, c3vec3_add(a, S));
- c3vertex_array_add(v, c3vec3_add(a, N));
- c3vertex_array_add(v, c3vec3_add(b, S));
- c3vertex_array_add(v, c3vec3_add(b, N));
- c3vertex_array_add(v, c3vec3_add(b, SE));
- c3vertex_array_add(v, c3vec3_add(b, NE));
-#endif
-
- const float ts = 1;
-
- c3vertex_array_add(v, c3vec3_add(a, SW));
- c3vertex_array_add(v, c3vec3_add(a, S));
- c3vertex_array_add(v, c3vec3_add(a, NW));
- c3tex_array_add(tex, c3vec2f(ts * 0 , ts * 0 ));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0 ));
- c3tex_array_add(tex, c3vec2f(ts * 0 , ts * 1 ));
-
- c3vertex_array_add(v, c3vec3_add(a, S));
- c3vertex_array_add(v, c3vec3_add(a, N));
- c3vertex_array_add(v, c3vec3_add(a, NW));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0 ));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1 ));
- c3tex_array_add(tex, c3vec2f(ts * 0 , ts * 1 ));
-
- c3vertex_array_add(v, c3vec3_add(a, N));
- c3vertex_array_add(v, c3vec3_add(b, S));
- c3vertex_array_add(v, c3vec3_add(b, N));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1 ));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0 ));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1 ));
-
- c3vertex_array_add(v, c3vec3_add(a, N));
- c3vertex_array_add(v, c3vec3_add(a, S));
- c3vertex_array_add(v, c3vec3_add(b, S));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1 ));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0 ));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0 ));
-
- c3vertex_array_add(v, c3vec3_add(b, N));
- c3vertex_array_add(v, c3vec3_add(b, S));
- c3vertex_array_add(v, c3vec3_add(b, SE));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1 ));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 0 ));
- c3tex_array_add(tex, c3vec2f(ts * 1 , ts * 0 ));
-
- c3vertex_array_add(v, c3vec3_add(b, N));
- c3vertex_array_add(v, c3vec3_add(b, SE));
- c3vertex_array_add(v, c3vec3_add(b, NE));
- c3tex_array_add(tex, c3vec2f(ts * 0.5, ts * 1 ));
- c3tex_array_add(tex, c3vec2f(ts * 1 , ts * 0 ));
- c3tex_array_add(tex, c3vec2f(ts * 1 , ts * 1 ));
-
- }
-}
-
-void
-c3lines_init(
- c3geometry_p g,
- c3vertex_p vertices, // points A,B pairs
- size_t count,
- c3f lineWidth)
-{
- c3mat4 i = identity3D();
- c3lines_prepare(vertices, count, &g->vertice, &g->textures, lineWidth, &i);
- g->type.type = C3_LINES_TYPE;
-}
-
-#if 0
-static void
-_c3lines_project(
- c3geometry_p g,
- const struct c3driver_geometry_t *d,
- c3mat4p m)
-
-const c3driver_geometry_t c3lines_driver = {
- .project = _c3lines_project,
-};
-
-const c3driver_geometry_t c3geometry_driver;
-
-c3geometry_set_lines(
- c3f lineWidth)
-{
- static const c3driver_geometry_t * list[] = {
- &c3lines_driver, &c3geometry_driver, NULL,
- };
-}
-#endif
+++ /dev/null
-/*
- c3lines.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3LINES_H___
-#define __C3LINES_H___
-
-#include "c3geometry.h"
-
-enum {
- C3_LINES_TYPE = C3_TYPE('l','i','n','e'),
-};
-/*
- * Takes an array of points A,B and split it into 'fat' lines around
- * lineWidth, generates an array of triangles and an array of corresponding
- * texture coordinates. Can also do a projection at the same time
- * TODO: Add array indices
- */
-void
-c3lines_prepare(
- c3vertex_p vertices, // points A,B pairs
- size_t count,
- c3vertex_array_p v, // triangles
- c3tex_array_p tex,
- c3f lineWidth,
- c3mat4p m);
-
-void
-c3lines_init(
- c3geometry_p g,
- c3vertex_p vertices, // points A,B pairs
- size_t count,
- c3f lineWidth);
-
-#endif /* __C3LINES_H___ */
+++ /dev/null
-/*
- c3object.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3object.h"
-#include "c3context.h"
-#include "c3driver_object.h"
-
-void
-_c3object_clear(
- c3object_p o,
- const c3driver_object_t * d)
-{
- for (int oi = 0; oi < o->transform.count; oi++) {
- o->transform.e[oi]->object = NULL;
- c3transform_dispose(o->transform.e[oi]);
- }
- for (int oi = 0; oi < o->geometry.count; oi++) {
- o->geometry.e[oi]->object = NULL; // don't try to detach
- c3geometry_dispose(o->geometry.e[oi]);
- }
- for (int oi = 0; oi < o->objects.count; oi++) {
- o->objects.e[oi]->parent = NULL; // don't try to detach
- c3object_dispose(o->objects.e[oi]);
- }
- c3object_array_free(&o->objects);
- c3geometry_array_free(&o->geometry);
- c3transform_array_free(&o->transform);
-}
-
-void
-_c3object_dispose(
- c3object_p o,
- const c3driver_object_t * d)
-{
- if (o->parent) {
- for (int oi = 0; oi < o->parent->objects.count; oi++)
- if (o->parent->objects.e[oi] == o) {
- c3object_array_delete(&o->parent->objects, oi, 1);
- c3object_set_dirty(o->parent, true);
- break;
- }
- o->parent = NULL;
- }
- //C3O_DRIVER_INHERITED(dispose, d);
- free(o);
-}
-
-void
-_c3object_get_geometry(
- c3object_p o,
- const c3driver_object_t * d,
- c3geometry_array_p out)
-{
- // if this object is not visible in this view, exit
- // there will be no geometry, so no drawing
- uint16_t viewmask = (1 << o->context->current);
- if (o->hidden & viewmask)
- return;
- for (int oi = 0; oi < o->geometry.count; oi++) {
- c3geometry_p g = o->geometry.e[oi];
- if (!(g->hidden & viewmask))
- c3geometry_array_add(out, g);
- }
- for (int oi = 0; oi < o->objects.count; oi++)
- c3object_get_geometry(o->objects.e[oi], out);
-}
-
-void
-_c3object_project(
- c3object_p o,
- const c3driver_object_t * d,
- c3mat4p m)
-{
- o->world = *m;
- if (!o->dirty)
- return;
- c3mat4 p = *m;
- for (int pi = 0; pi < o->transform.count; pi++)
- p = c3mat4_mul(&p, &o->transform.e[pi]->matrix);
- o->world = p;
-
- for (int gi = 0; gi < o->geometry.count; gi++) {
- c3geometry_p g = o->geometry.e[gi];
- c3geometry_project(g, &p);
- }
- for (int oi = 0; oi < o->objects.count; oi++)
- c3object_project(o->objects.e[oi], &p);
- o->dirty = false;
-}
-
-const c3driver_object_t c3object_driver = {
- .clear = _c3object_clear,
- .dispose = _c3object_dispose,
- .get_geometry = _c3object_get_geometry,
- .project = _c3object_project,
-};
-
-
-c3object_p
-c3object_init(
- c3object_p o /* = NULL */,
- c3object_p parent)
-{
- memset(o, 0, sizeof(*o));
- o->parent = parent;
- static const c3driver_object_t * list[] =
- { &c3object_driver, NULL };
- o->driver = list;
- if (parent) {
- c3object_array_add(&parent->objects, o);
- o->context = parent->context;
- }
- return o;
-}
-
-c3object_p
-c3object_new(
- c3object_p o /* = NULL */)
-{
- c3object_p res = malloc(sizeof(*o));
- return c3object_init(res, o);
-}
-
-void
-c3object_clear(
- c3object_p o)
-{
- C3_DRIVER(o, clear);
-}
-
-void
-c3object_dispose(
- c3object_p o)
-{
- c3object_clear(o);
- C3_DRIVER(o, dispose);
-}
-
-void
-c3object_set_dirty(
- c3object_p o,
- bool dirty)
-{
- if (dirty) {
- // also mark all our geometry dirty
- for (int oi = 0; oi < o->geometry.count; oi++)
- if (o->geometry.e[oi])
- o->geometry.e[oi]->dirty = 1;
- while (o) {
- o->dirty = true;
- o = o->parent;
- }
- } else {
- for (int oi = 0; oi < o->objects.count; oi++)
- if (o->objects.e[oi]->dirty)
- c3object_set_dirty(o->objects.e[oi], false);
- o->dirty = false;
- }
-}
-
-void
-c3object_add_object(
- c3object_p o,
- c3object_p sub)
-{
- if (sub->parent == o)
- return;
- if (sub->parent) {
- for (int oi = 0; oi < sub->parent->objects.count; oi++) {
- if (sub->parent->objects.e[oi] == sub) {
- c3object_array_delete(&sub->parent->objects, oi, 1);
- c3object_set_dirty(sub->parent, true);
- break;
- }
- }
- sub->parent = NULL;
- }
- sub->parent = o;
- if (o) {
- c3object_array_add(&o->objects, sub);
- c3object_set_dirty(o, true);
- }
-}
-
-void
-c3object_add_geometry(
- c3object_p o,
- c3geometry_p g)
-{
- if (g->object == o)
- return;
- if (g->object) {
- for (int oi = 0; oi < g->object->geometry.count; oi++) {
- if (g->object->geometry.e[oi] == g) {
- c3geometry_array_delete(&g->object->geometry, oi, 1);
- c3object_set_dirty(g->object, true);
- break;
- }
- }
- g->object = NULL;
- }
- g->object = o;
- if (o) {
- c3geometry_array_add(&o->geometry, g);
- c3object_set_dirty(o, true);
- }
-}
-
-void
-c3object_get_geometry(
- c3object_p o,
- c3geometry_array_p array )
-{
- C3_DRIVER(o, get_geometry, array);
-}
-
-void
-c3object_project(
- c3object_p o,
- const c3mat4p m)
-{
- C3_DRIVER(o, project, m);
-}
+++ /dev/null
-/*
- c3object.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3OBJECT_H___
-#define __C3OBJECT_H___
-
-#include <stdbool.h>
-#include "c3transform.h"
-#include "c3geometry.h"
-
-struct c3object_t;
-
-DECLARE_C_ARRAY(struct c3object_t*, c3object_array, 4);
-
-//! c3object is a container for child object, and geometry
-/*!
- * a c3object is a node in a c3object tree, it contains sub-objects and/or
- * geometry. It also contains it's own list of transform matrices, so can
- * be seen as a "anchor" that can be moved around and where you can
- * attach other objects or geometry.
- *
- * An object has a notion of 'dirty bit' -- something that signals that
- * something has changed and deserved reprojection. the dirty bit
- * is propagated upward when 1 (up to the root object) and downward when 0
- * (to allow clearing the bit on a subtree)
- */
-typedef struct c3object_t {
- str_p name; //! optional name
- int dirty : 1,
- hidden : 8 /* hidden bit mask, related to c3context's views */;
- struct c3context_t * context; //! context this object is attached to
- struct c3object_t * parent; //! Parent object
- const struct c3driver_object_t ** driver; //! Driver stack
-
- c3mat4 world; // calculated world coordinates
- c3transform_array_t transform;
- c3object_array_t objects; //! child object list
- c3geometry_array_t geometry; //! Object geometri(es)
-} c3object_t, *c3object_p;
-
-//! Allocates and initialize an emty object, attaches it to parent 'o'
-c3object_p
-c3object_new(
- c3object_p o /* = NULL */);
-//! Disposes of everything under this object
-void
-c3object_dispose(
- c3object_p o);
-//! Clears every sub-object, geometry, and transform, but do not dispose of o
-void
-c3object_clear(
- c3object_p o);
-//! Initializes 'o' as a new object, attaches it to parent (optional)
-c3object_p
-c3object_init(
- c3object_p o,
- c3object_p parent /* = NULL */);
-//! sets the dirty bit for 'o' and related tree
-/*!
- * When dirty is 1, sets the dirty bit of this object and all the parent
- * objects up to the root object.
- * When dirty is 0, clear the dirty bit of this object, and all the
- * sub objects.
- */
-void
-c3object_set_dirty(
- c3object_p o,
- bool dirty);
-//! Adds a new geometry g to object o
-void
-c3object_add_geometry(
- c3object_p o,
- c3geometry_p g);
-//! Adds a new sub-object sub to object o
-void
-c3object_add_object(
- c3object_p o,
- c3object_p sub);
-//! Adds a new transform matrix, initialized as identity
-c3transform_p
-c3object_add_transform(
- c3object_p o );
-//! Iterates all the sub-objects and collects all the geometries
-/*!
- * This call iterates the sub-objects and collects all their 'projected'
- * geometry, and add them to the array
- */
-void
-c3object_get_geometry(
- c3object_p o,
- c3geometry_array_p array );
-//! Project object 'o' using it's own transformations, relative to matrix 'm'
-/*!
- * Multiply this objects transformation(s) to matrix 'm' and calls
- * reprojects the geometries using that matrix as an anchor. also call
- * recursively to sub-objects to follow the projection down.
- */
-void
-c3object_project(
- c3object_p o,
- const c3mat4p m);
-
-IMPLEMENT_C_ARRAY(c3object_array);
-
-#endif /* __C3OBJECT_H___ */
+++ /dev/null
-/*
- c3pixels.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "c3pixels.h"
-
-c3pixels_p
-c3pixels_new(
- uint32_t w,
- uint32_t h,
- int psize /* in bytes */,
- size_t row,
- void * base)
-{
- c3pixels_p p = malloc(sizeof(*p));
- c3pixels_init(p, w, h, psize, row, base);
- p->alloc = 1;
- return p;
-}
-
-c3pixels_p
-c3pixels_init(
- c3pixels_p p,
- uint32_t w,
- uint32_t h,
- int psize /* in bytes */,
- size_t row,
- void * base)
-{
- memset (p, 0, sizeof(*p));
- p->w = w;
- p->h = h;
- p->row = row;
- p->psize = psize;
- p->base = base;
- c3pixels_alloc(p);
- return p;
-}
-
-void
-c3pixels_dispose(
- c3pixels_p p )
-{
- if (p->own && p->base)
- free(p->base);
- if (p->alloc)
- free(p);
- else
- memset(p, 0, sizeof(*p));
-}
-
-void
-c3pixels_alloc(
- c3pixels_p p )
-{
- if (p->base)
- return;
- p->base = malloc(p->row * p->h);
- p->own = p->base != NULL;
-}
-
-void
-c3pixels_purge(
- c3pixels_p p )
-{
- if (!p->base)
- return;
- if (p->own)
- free(p->base);
- p->own = 0;
- p->base = NULL;
-}
-
-void
-c3pixels_zero(
- c3pixels_p p)
-{
- if (!p->base)
- return;
- memset(p->base, 0, p->h * p->row);
-}
+++ /dev/null
-/*
- c3pixels.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3PIXELS_H___
-#define __C3PIXELS_H___
-
-#include "c3types.h"
-#include "c_utils.h"
-
-//! for format hint
-enum {
- C3PIXEL_ARGB = 0,
- C3PIXEL_RGB,
- C3PIXEL_A
-};
-
-typedef struct c3pixels_t {
- str_p name; // optional
- uint32_t w, h; // width & height in pixels
- size_t row; // size of one row in bytes
- void * base; // base address
-
- union {
- struct {
- uint32_t own : 1, // is the base our own to delete
- alloc : 1, // is the c3pixels_p our own to delete
- dirty : 1, // pixels have been changed
- psize : 4, // pixel size in byte
- normalize : 1, // texture coordinates are 0...1
- trace : 1, // debug
- format : 8; // not used internally
- };
- uint32_t flags;
- };
- c3apiobject_t texture;
- int refCount; // TODO: Implement reference counting ?
-} c3pixels_t, *c3pixels_p;
-
-DECLARE_C_ARRAY(c3pixels_p, c3pixels_array, 4);
-
-//! Allocates a new c3pixels, also allocates the pixels if row == NULL
-c3pixels_p
-c3pixels_new(
- uint32_t w,
- uint32_t h,
- int psize /* in bytes */,
- size_t row,
- void * base);
-
-//! Initializes p, also allocates the pixels if row == NULL
-c3pixels_p
-c3pixels_init(
- c3pixels_p p,
- uint32_t w,
- uint32_t h,
- int psize /* in bytes */,
- size_t row,
- void * base);
-
-//! Dispose of the pixels, and potentially p if it was allocated with c3pixels_new
-void
-c3pixels_dispose(
- c3pixels_p p );
-
-//! Disposes of the pixels, only
-void
-c3pixels_purge(
- c3pixels_p p );
-
-//! (Re)allocate pixels if pixels had been purged
-void
-c3pixels_alloc(
- c3pixels_p p );
-
-//! Get a pixel address
-static inline void *
-c3pixels_get(
- c3pixels_p p,
- int x, int y)
-{
- return ((uint8_t*)p->base) + (y * p->row) + (x * p->psize);
-}
-
-//! Zeroes the pixels
-void
-c3pixels_zero(
- c3pixels_p p);
-
-IMPLEMENT_C_ARRAY(c3pixels_array);
-
-#endif /* __C3PIXELS_H___ */
+++ /dev/null
-/*
- c3program.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-#include <fcntl.h>
-
-#include "c3program.h"
-
-c3program_p
-c3program_new(
- const char * name,
- const char ** uniforms )
-{
- c3program_p p = malloc(sizeof(*p));
- memset(p, 0, sizeof(*p));
- p->name = str_new(name);
-
- /* Allow specifying uniform names to make sure they are in
- * the specified order in the array, this allow direct indexing
- * instead of doign string lookup
- */
- if (uniforms) {
- for (int ui = 0; uniforms[ui]; ui++) {
- c3program_param_t pa = {
- .name = str_new(uniforms[ui]),
- .program = p,
- .index = p->params.count,
- };
- c3program_param_array_add(&p->params, pa);
- }
- }
- return p;
-}
-
-void
-c3program_dispose(
- c3program_p p)
-{
- c3program_purge(p);
- for (int pi = 0; pi < p->params.count; pi++) {
- c3program_param_p pa = &p->params.e[pi];
- str_free(pa->name);
- }
- c3program_param_array_free(&p->params);
- str_free(p->name);
- str_free(p->log);
- free(p);
-}
-
-void
-c3program_purge(
- c3program_p p)
-{
- for (int si = 0; si < p->shaders.count; si++) {
- c3shader_p s = &p->shaders.e[si];
- str_free(s->name);
- str_free(s->shader);
- }
- c3shader_array_free(&p->shaders);
-}
-
-c3program_param_p
-c3program_locate_param(
- c3program_p p,
- const char * name )
-{
- for (int pi = 0; pi < p->params.count; pi++)
- if (!strcmp(p->params.e[pi].name->str, name))
- return &p->params.e[pi];
- return NULL;
-}
-
-int
-c3program_load_shader(
- c3program_p p,
- uint32_t type,
- const char * header,
- const char * filename,
- uint16_t flags)
-{
- struct stat st;
- str_p pgm = NULL;
-
- if (stat(filename, &st))
- goto error;
- int fd = open(filename, O_RDONLY);
- if (fd == -1)
- goto error;
-
- int hlen = header ? strlen(header) : 0;
- pgm = str_alloc(st.st_size + hlen);
- if (header)
- strcpy(pgm->str, header);
-
- if (read(fd, pgm->str + hlen, st.st_size) != st.st_size)
- goto error;
- close(fd);
- pgm->str[pgm->len] = 0; // zero terminate it
-
- c3shader_t s = {
- .type = type,
- .name = str_new(filename),
- .shader = pgm,
- };
- c3shader_array_add(&p->shaders, s);
-
- if (flags & C3_PROGRAM_LOAD_UNIFORM) {
- char * cur = pgm->str;
- char * l;
-
- while ((l = strsep(&cur, "\r\n")) != NULL) {
- while (*l && *l <= ' ')
- l++;
- str_p line = str_new(l);
- if (cur) // fix the endline after strsep
- *(cur-1) = '\n';
- if (strncmp(line->str, "uniform", 7))
- continue;
- // printf("UNI: %s\n", line->str);
-
- char * sep = line->str;
- char * uniform = strsep(&sep, " \t");
- char * unitype = strsep(&sep, " \t");
- char * uniname = strsep(&sep, " \t=;");
- /*
- * found a parameter, extract it's type & name
- */
- if (uniform && unitype && uniname) {
- // trim semicolons etc
- char *cl = uniname;
- while (isalpha(*cl) || *cl == '_' || isdigit(*cl))
- cl++;
- *cl = 0;
- str_p name = str_new(uniname);
- for (int pi = 0; pi < p->params.count && uniform; pi++)
- if (!str_cmp(name, p->params.e[pi].name)) {
- if (!p->params.e[pi].type)
- p->params.e[pi].type = str_new(unitype);
- uniform = NULL; // already there
- }
- if (uniform) {
- c3program_param_t pa = {
- .type = str_new(unitype),
- .name = name,
- .program = p,
- .index = p->params.count,
- };
- c3program_param_array_add(&p->params, pa);
- if (p->verbose)
- printf("%s %s: new parameter '%s' '%s'\n", __func__,
- p->name->str, unitype, uniname);
- } else
- str_free(name);
- }
- str_free(line);
- }
- }
- return p->shaders.count - 1;
-
-error:
- if (fd != -1)
- close(fd);
- if (pgm)
- str_free(pgm);
- fprintf(stderr, "%s: %s: %s\n", __func__, filename, strerror(errno));
- return -1;
-
-}
+++ /dev/null
-/*
- c3program.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3PROGRAM_H___
-#define __C3PROGRAM_H___
-
-#include "c3types.h"
-#include "c_utils.h"
-
-typedef struct c3shader_t {
- c3apiobject_t sid; // shader id
- uint32_t type;
- str_p name;
- str_p shader;
-} c3shader_t, *c3shader_p;
-
-DECLARE_C_ARRAY(c3shader_t, c3shader_array, 4);
-
-typedef struct c3program_param_t {
- struct c3program_t * program;
- int index; // index number in paramerer array
- c3apiobject_t pid; // parameter id
- str_p type;
- str_p name;
-} c3program_param_t, *c3program_param_p;
-
-DECLARE_C_ARRAY(c3program_param_t, c3program_param_array, 4);
-
-typedef struct c3program_t {
- c3apiobject_t pid; // program id
- int verbose : 1;
- str_p name;
- c3shader_array_t shaders;
- c3program_param_array_t params;
- str_p log; // if an error occurs
-} c3program_t, *c3program_p;
-
-DECLARE_C_ARRAY(c3program_p, c3program_array, 4);
-
-//! Allocates a new, empty program
-/* if 'uniforms' is non null it is a NULL terminated array of
- * uniform names to pre-add to the uniform array in the specified
- * order.
- * This make sure they are in the specified order in the array,
- * to allow direct indexing instead of doing string lookup by name
- */
-c3program_p
-c3program_new(
- const char * name,
- const char ** uniforms /* optional */);
-
-//! disposes of a c3program memory
-void
-c3program_dispose(
- c3program_p p);
-
-//! purge deletes the shader storage, but keep the program and parameters
-void
-c3program_purge(
- c3program_p p);
-
-enum {
- C3_PROGRAM_LOAD_UNIFORM = (1 << 0),
-};
-
-int
-c3program_load_shader(
- c3program_p p,
- uint32_t type,
- const char * header,
- const char * filename,
- uint16_t flags);
-
-c3program_param_p
-c3program_locate_param(
- c3program_p p,
- const char * name );
-
-IMPLEMENT_C_ARRAY(c3program_param_array);
-IMPLEMENT_C_ARRAY(c3shader_array);
-IMPLEMENT_C_ARRAY(c3program_array);
-
-#endif /* __C3PROGRAM_H___ */
+++ /dev/null
-/*
- c3quaternion.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <math.h>
-#include "c3quaternion.h"
-
-#ifndef DEG2RAD
-#define DEG2RAD(x) ((x)/180.0*M_PI)
-#define RAD2DEG(x) ((x)/M_PI*180.0)
-#endif
-#ifndef FUDGE
-#define FUDGE .00001
-#endif
-
-c3quat
-c3quat_new()
-{
- return c3quat_identity();
-}
-
-/************************************************* c3quat_identity() *****/
-/* Returns quaternion identity element */
-
-c3quat
-c3quat_identity()
-{
- return c3quat_vec3( c3vec3f( 0.0, 0.0, 0.0 ), 1.0 );
-}
-
-c3quat
-c3quatf(
- const c3f x,
- const c3f y,
- const c3f z,
- const c3f w)
-{
- c3quat q = { .v = c3vec3f(x,y,z), .s = w };
- return q;
-}
-
-c3quat
-c3quat_vec3(
- const c3vec3 v,
- const c3f s)
-{
- c3quat q = { .v = v, .s = s };
- return q;
-}
-
-c3quat
-c3quat_vec4(
- const c3vec4 v)
-{
- c3quat q = { .v = c3vec3f(v.n[0], v.n[1], v.n[2]), .s = v.n[3] };
- return q;
-}
-
-c3quat
-c3quat_double(
- const double *d)
-{
- c3quat q;
- q.v.n[0] = (c3f) d[0];
- q.v.n[1] = (c3f) d[1];
- q.v.n[2] = (c3f) d[2];
- q.s = (c3f) d[3];
- return q;
-}
-
-
-c3quat
-c3quat_add(
- const c3quat a,
- const c3quat b)
-{
- return c3quat_vec3(c3vec3_add(a.v, b.v), a.s + b.s );
-}
-
-c3quat
-c3quat_sub(
- const c3quat a,
- const c3quat b)
-{
- return c3quat_vec3(c3vec3_sub(a.v, b.v), a.s - b.s );
-}
-
-c3quat
-c3quat_minus(
- const c3quat a )
-{
- return c3quat_vec3(c3vec3_minus(a.v), -a.s);
-}
-
-c3quat
-c3quat_mul(
- const c3quat a,
- const c3quat b)
-{
-// return c3quat( a.s*b.s - a.v*b.v, a.s*b.v + b.s*a.v + a.v^b.v );
- return c3quat_vec3(
- c3vec3_add(c3vec3_mulf(b.v, a.s), c3vec3_add(c3vec3_mulf(a.v, b.s), c3vec3_cross(a.v, b.v))),
- (a.s * b.s) - c3vec3_dot(a.v, b.v));
-}
-
-c3quat
-c3quat_mulf( const c3quat a, const c3f t)
-{
- return c3quat_vec3(c3vec3_mulf(a.v, t), a.s * t );
-}
-
-c3mat4
-c3quat_to_mat4(
- const c3quat a )
-{
- c3f xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
-
- c3f t = 2.0f / (c3vec3_dot(a.v, a.v) + (a.s * a.s));
-
- xs = a.v.n[VX]*t; ys = a.v.n[VY]*t; zs = a.v.n[VZ]*t;
- wx = a.s*xs; wy = a.s*ys; wz = a.s*zs;
- xx = a.v.n[VX]*xs; xy = a.v.n[VX]*ys; xz = a.v.n[VX]*zs;
- yy = a.v.n[VY]*ys; yz = a.v.n[VY]*zs; zz = a.v.n[VZ]*zs;
-
- c3mat4 m = c3mat4_vec4(
- c3vec4f(1.0f-(yy+zz), xy+wz, xz-wy, 0.0f),
- c3vec4f(xy-wz, 1.0f-(xx+zz), yz+wx, 0.0f),
- c3vec4f(xz+wy, yz-wx, 1.0f-(xx+yy), 0.0f),
- c3vec4f(0.0f, 0.0f, 0.0f, 1.0f ));
-
- return m;
-}
-
-
-/************************************************ quat_slerp() ********/
-/* Quaternion spherical interpolation */
-
-c3quat
-quat_slerp(
- const c3quat from,
- const c3quat to,
- c3f t)
-{
- c3quat to1;
- c3f omega, cosom, sinom, scale0, scale1;
-
- /* calculate cosine */
- cosom = c3vec3_dot(from.v, to.v) + from.s + to.s;
-
- /* Adjust signs (if necessary) */
- if (cosom < 0.0) {
- cosom = -cosom;
- to1 = c3quat_minus(to);
- } else {
- to1 = to;
- }
-
- /* Calculate coefficients */
- if ((1.0 - cosom) > FUDGE ) {
- /* standard case (slerp) */
- omega = (c3f) acos( cosom );
- sinom = (c3f) sin( omega );
- scale0 = (c3f) sin((1.0 - t) * omega) / sinom;
- scale1 = (c3f) sin(t * omega) / sinom;
- } else {
- /* 'from' and 'to' are very close - just do linear interpolation */
- scale0 = 1.0f - t;
- scale1 = t;
- }
-
- return c3quat_add(c3quat_mulf(from, scale0), c3quat_mulf(to1, scale1));
-}
-
-/********************************************** set_angle() ************/
-/* set rot angle (degrees) */
-
-c3quatp
-c3quat_set_angle(
- c3quatp a,
- c3f f)
-{
- c3vec3 axis = c3quat_get_axis(a);
-
- a->s = (c3f) cos( DEG2RAD( f ) / 2.0 );
-
- a->v = c3vec3_mulf(axis, (c3f) sin(DEG2RAD(f) / 2.0));
- return a;
-}
-
-/********************************************** scale_angle() ************/
-/* scale rot angle (degrees) */
-
-c3quatp
-c3quat_scale_angle(
- c3quatp a,
- c3f f)
-{
- return c3quat_set_angle(a, f * c3quat_get_angle(a) );
-}
-
-/********************************************** get_angle() ************/
-/* get rot angle (degrees). Assumes s is between -1 and 1 */
-
-c3f
-c3quat_get_angle(
- const c3quatp a)
-{
- return (c3f) RAD2DEG( 2.0 * acos( a->s ) );
-}
-
-/********************************************* get_axis() **************/
-
-c3vec3
-c3quat_get_axis(
- c3quatp a)
-{
- c3f scale = (c3f) sin( acos( a->s ) );
-
- if ( scale < FUDGE && scale > -FUDGE )
- return c3vec3f( 0.0, 0.0, 0.0 );
- else
- return c3vec3_divf(a->v, scale);
-}
-
-/******************************************* c3quat_print() ************/
-#if 0
-void c3quat_print(FILE *dest, const char *name) const
-{
- fprintf( dest, "%s: v:<%3.2f %3.2f %3.2f> s:%3.2f\n",
- name, v[0], v[1], v[2], s );
-}
-#endif
+++ /dev/null
-/*
- c3quaternion.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3QUATERNION_H___
-#define __C3QUATERNION_H___
-
-#include <stdbool.h>
-#include "c3algebra.h"
-
-typedef struct c3quat {
- c3vec3 v; /* vector component */
- c3f s; /* scalar component */
-} c3quat, *c3quatp;
-
-c3quat
-c3quat_new();
-c3quat
-c3quat_identity();
-
-c3quat
-c3quatf(
- const c3f x,
- const c3f y,
- const c3f z,
- const c3f w);
-c3quat
-c3quat_vec3(
- const c3vec3 v,
- const c3f s);
-c3quat
-c3quat_vec4(
- const c3vec4 v);
-
-c3quat
-c3quat_double(
- const double *d);
-
-c3quat
-c3quat_add(
- const c3quat a,
- const c3quat b);
-c3quat
-c3quat_sub(
- const c3quat a,
- const c3quat b);
-c3quat
-c3quat_minus(
- const c3quat a );
-
-c3quat
-c3quat_mul(
- const c3quat a,
- const c3quat b);
-
-c3mat4
-c3quat_to_mat4(
- const c3quat a );
-
-c3quatp
-c3quat_set_angle(
- c3quatp a,
- c3f f);
-c3quatp
-c3quat_scale_angle(
- c3quatp a,
- c3f f);
-c3f
-c3quat_get_angle(
- const c3quatp a);
-c3vec3
-c3quat_get_axis(
- c3quatp a);
-
-#endif /* __C3QUATERNION_H___ */
+++ /dev/null
-/*
- c3sphere.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include <math.h>
-#include "c3geometry.h"
-#include "c3sphere.h"
-
-c3geometry_p
-c3sphere_uv(
- struct c3object_t * parent,
- c3vec3 center,
- c3f radius,
- int rings,
- int sectors )
-{
- float const R = 1. / (float) (rings - 1);
- float const S = 1. / (float) (sectors - 1);
-
- c3geometry_p g = c3geometry_new(c3geometry_type(C3_SPHERE_TYPE, 0), parent);
-
- c3vertex_array_realloc(&g->vertice, rings * sectors);
- c3vertex_array_realloc(&g->normals, rings * sectors);
- c3tex_array_realloc(&g->textures, rings * sectors);
- c3indices_array_realloc(&g->indices, rings * sectors * 6);
-
- for (int r = 0; r < rings; r++)
- for (int s = 0; s < sectors; s++) {
- float const y = sin(-M_PI_2 + M_PI * r * R);
- float const x = cos(2 * M_PI * s * S) * sin(M_PI * r * R);
- float const z = sin(2 * M_PI * s * S) * sin(M_PI * r * R);
-
- c3tex_array_add(&g->textures, c3vec2f(s * S, r * R));
- c3vertex_array_add(&g->vertice,
- c3vec3_add(center, c3vec3f(x * radius, y * radius, z * radius)));
- c3vertex_array_add(&g->normals, c3vec3_normalize(c3vec3f(x, y, z)));
- }
-
- for (int r = 0; r < rings - 1; r++)
- for (int s = 0; s < sectors - 1; s++) {
- uint16_t i[6] = {
- r * sectors + (s + 1), r * sectors + s, (r + 1) * sectors + (s + 1),
- (r + 1) * sectors + (s + 1), r * sectors + s, (r + 1) * sectors + s,
- };
- c3indices_array_insert(&g->indices, g->indices.count, i, 6);
- }
- return g;
-}
-
+++ /dev/null
-/*
- c3sphere.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3SPHERE_H___
-#define __C3SPHERE_H___
-
-#include "c3algebra.h"
-
-enum {
- C3_SPHERE_TYPE = C3_TYPE('s','p','h','e'),
-};
-
-struct c3geometry_t *
-c3sphere_uv(
- struct c3object_t * parent,
- c3vec3 center,
- c3f radius,
- int rings,
- int sectors );
-
-#endif /* __C3SPHERE_H___ */
+++ /dev/null
-/*
- c3stl.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include "c3algebra.h"
-#include "c3geometry.h"
-#include "c3object.h"
-#include "c3stl.h"
-
-enum {
- vertex_None = -1,
- vertex_Vertex,
- vertex_Normal,
-};
-
-static int
-_c3stl_read_vertex(
- char * vt,
- c3vec3 * out )
-{
- int res = 1;
- char *l = vt;
- /*char * key =*/ strsep(&l, " \t");
- char * x = strsep(&l, " \t");
- char * y = strsep(&l, " \t");
- char * z = strsep(&l, " \t");
-
- if (x) sscanf(x, "%f", out->n);
- if (y) sscanf(y, "%f", out->n + 1);
- if (z) sscanf(z, "%f", out->n + 2);
-// printf("'%s' '%s' '%s' '%s' = %.2f %.2f %.2f\n",
-// key, x, y, z, out->n[0], out->n[1], out->n[2]);
- return res;
-}
-
-struct c3object_t *
-c3stl_load(
- const char * filename,
- c3object_p parent)
-{
- FILE *f = fopen(filename, "r");
- if (!f) {
- perror(filename);
- return NULL;
- }
-
- c3object_p o = c3object_new(parent);
- c3geometry_p current_g = NULL;
- o->name = str_new(filename);
-
- int state = 0;
- while (!feof(f)) {
- char line[256];
-
- fgets(line, sizeof(line), f);
-
- int l = strlen(line);
- while (l && line[l-1] < ' ')
- line[--l] = 0;
- if (!l)
- continue;
- char * keyword = line;
- while (*keyword && *keyword <= ' ')
- keyword++;
- l = strlen(keyword);
- // printf("%d>'%s'\n", state, keyword);
-
- switch (state) {
- case 0: //
- if (!strncmp(keyword, "solid ", 6)) {
- char * n = keyword + 6;
- current_g = c3geometry_new(c3geometry_type(C3_TRIANGLE_TYPE, 0), o);
- current_g->name = str_new(n);
-
- state = 1;
- }
- break;
- case 1: //
- if (!strncmp(keyword, "facet ", 6)) {
- c3vec3 normal;
- _c3stl_read_vertex(keyword + 6, &normal);
- normal = c3vec3_normalize(normal);
- c3vertex_array_add(¤t_g->normals, normal);
- c3vertex_array_add(¤t_g->normals, normal);
- c3vertex_array_add(¤t_g->normals, normal);
- state = 2;
- } else if (!strncmp(keyword, "endsolid ", 9))
- state = 0;
- break;
- case 2:
- if (!strncmp(keyword, "outer loop", 10))
- state = 3;
- else if (!strncmp(keyword, "endfacet", 8))
- state = 1;
- break;
- case 3:
- if (!strncmp(keyword, "vertex ", 7)) {
- c3vec3 v;
- _c3stl_read_vertex(keyword, &v);
- c3vertex_array_add(¤t_g->vertice, v);
- state = 3;
- } else if (!strncmp(keyword, "endloop", 7))
- state = 2;
- break;
- }
- }
-
- fclose(f);
- return o;
-}
+++ /dev/null
-/*
- c3stl.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3STL_H___
-#define __C3STL_H___
-
-/*
- * Loads an ASCII (TODO: Load STL Binary?) STL file as a c3object with
- * a set of c3geometries with the triangles
- */
-struct c3object_t *
-c3stl_load(
- const char * filename,
- struct c3object_t * parent);
-
-#endif /* __C3STL_H___ */
+++ /dev/null
-/*
- c3texture.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include <stdio.h>
-#include "c3texture.h"
-#include "c3driver_geometry.h"
-
-void
-_c3texture_dispose(
- c3geometry_p g,
- const c3driver_geometry_t * d)
-{
-// c3texture_p t = (c3texture_p)g;
- C3_DRIVER_INHERITED(g, d, dispose);
-}
-
-void
-_c3texture_project(
- c3geometry_p g,
- const c3driver_geometry_t * d,
- c3mat4p m)
-{
- c3texture_p t = (c3texture_p)g;
- c3pixels_p p = t->geometry.mat.texture;
- if (!p) {
- C3_DRIVER_INHERITED(g, d, project, m);
- return;
- }
- c3vec2 qs = c3vec2f(
- t->size.x > 0 ? t->size.x : p->w,
- t->size.y > 0 ? t->size.y : p->h);
- c3vec3 v[4] = {
- c3vec3f(0, 0, 0), c3vec3f(qs.x, 0, 0),
- c3vec3f(qs.x, qs.y, 0), c3vec3f(0, qs.y, 0)
- };
- c3vertex_array_clear(&g->vertice);
- c3vertex_array_realloc(&g->vertice, 4);
- c3vertex_array_insert(&g->vertice, 0, v, 4);
-
- c3f tw = p->normalize ? 1.0 : p->w,
- th = p->normalize ? 1.0 : p->h;
- c3vec2 ti[4] = {
- c3vec2f(0, th), c3vec2f(tw, th),
- c3vec2f(tw, 0), c3vec2f(0, 0)
- };
- if (p->trace)
- printf("%s size %.0fx%.0f tex %.0fx%.0f\n", __func__, qs.x, qs.y, tw, th);
- c3tex_array_clear(&t->geometry.textures);
- c3tex_array_realloc(&t->geometry.textures, 4);
- c3tex_array_insert(&t->geometry.textures, 0, ti, 4);
-
- C3_DRIVER_INHERITED(g, d, project, m);
-}
-
-const c3driver_geometry_t c3texture_driver = {
- .dispose = _c3texture_dispose,
- .project = _c3texture_project,
-};
-extern const c3driver_geometry_t c3geometry_driver;
-
-c3texture_p
-c3texture_new(
- struct c3object_t * o /* = NULL */)
-{
- c3texture_p res = malloc(sizeof(*res));
- return c3texture_init(res, o);
-}
-
-c3texture_p
-c3texture_init(
- c3texture_p t,
- struct c3object_t * o /* = NULL */)
-{
- memset(t, 0, sizeof(*t));
- c3geometry_init(&t->geometry,
- c3geometry_type(C3_TEXTURE_TYPE, 0 /* GL_TRIANGLE_FAN */),
- o);
- static const c3driver_geometry_t * list[] = {
- &c3texture_driver, &c3geometry_driver, NULL,
- };
- t->geometry.driver = list;
-
- return t;
-}
-
-void
-c3texture_resize(
- c3texture_p t,
- c3vec2 size )
-{
- t->size = size;
- t->geometry.dirty = 1;
- c3geometry_set_dirty(&t->geometry, 1);
-}
+++ /dev/null
-/*
- c3texture.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3TEXTURE_H___
-#define __C3TEXTURE_H___
-
-#include "c3geometry.h"
-#include "c3pixels.h"
-
-enum {
- C3_TEXTURE_TYPE = C3_TYPE('t','e','x','u'),
-};
-
-typedef struct c3texture_t {
- c3geometry_t geometry;
- c3vec2 size; // quad size
-} c3texture_t, *c3texture_p;
-
-c3texture_p
-c3texture_new(
- struct c3object_t * parent /* = NULL */);
-c3texture_p
-c3texture_init(
- c3texture_p t,
- struct c3object_t * parent /* = NULL */);
-void
-c3texture_resize(
- c3texture_p t,
- c3vec2 size );
-
-#endif /* __C3TEXTURE_H___ */
+++ /dev/null
-/*
- c3transform.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c3object.h"
-
-c3transform_p
-c3transform_new(
- c3object_p o )
-{
- c3transform_p res = malloc(sizeof(*res));
- res->matrix = identity3D();
- res->object = o;
- res->name = NULL;
- c3transform_array_add(&o->transform, res);
- return res;
-}
-
-void
-c3transform_dispose(
- c3transform_p t )
-{
- if (t->object) {
- for (int oi = 0; oi < t->object->transform.count; oi++)
- if (t->object->transform.e[oi] == t) {
- c3transform_array_delete(&t->object->transform, oi, 1);
- c3object_set_dirty(t->object, true);
- break;
- }
- t->object = NULL;
- }
- str_free(t->name);
- free(t);
-}
-
-void
-c3transform_set(
- c3transform_p t,
- const c3mat4p m )
-{
- if (c3mat4_equal(m, &t->matrix))
- return;
- t->matrix = *m;
- c3object_set_dirty(t->object, true);
-}
+++ /dev/null
-/*
- c3transform.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3TRANSFORM_H___
-#define __C3TRANSFORM_H___
-
-#include "c3algebra.h"
-#include "c_utils.h"
-
-typedef struct c3transform_t {
- str_p name;
- struct c3object_t * object;
- c3mat4 matrix;
-} c3transform_t, *c3transform_p;
-
-c3transform_p
-c3transform_new(
- struct c3object_t * o );
-void
-c3transform_set(
- c3transform_p t,
- c3mat4p m );
-void
-c3transform_dispose(
- c3transform_p t );
-
-DECLARE_C_ARRAY(c3transform_p, c3transform_array, 4);
-IMPLEMENT_C_ARRAY(c3transform_array);
-
-#endif /* __C3TRANSFORM_H___ */
+++ /dev/null
-/*
- c3types.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3TYPES_H___
-#define __C3TYPES_H___
-
-#include <stdint.h>
-#include "c3algebra.h"
-
-typedef c3vec3 c3vertex_t, *c3vertex_p;
-typedef c3vec4 c3colorf_t, *c3colorf_p;
-typedef c3vec2 c3tex_t, *c3tex_p;
-typedef uint16_t c3index_t, *c3index_p;
-
-/* this type is used to store an API object (texture id etc
- * it is made to force a cast in most cases as OpenGL uses integers
- * for object ids
- */
-typedef void * c3apiobject_t;
-
-//! Bounding box
-typedef struct c3bbox_t {
- c3vec3 min, max;
-} c3bbox_t;
-
-#endif /* __C3TYPES_H___ */
+++ /dev/null
-/*
- c_array.h
-
- Copyright 2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of gcodepp.
-
- gcodepp is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- gcodepp 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 gcodepp. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C_ARRAY_H___
-#define __C_ARRAY_H___
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef C_ARRAY_INLINE
-#define C_ARRAY_INLINE inline
-#endif
-#ifndef C_ARRAY_SIZE_TYPE
-#define C_ARRAY_SIZE_TYPE uint32_t
-#endif
-
-#define DECLARE_C_ARRAY(__type, __name, __page, __args...) \
-enum { __name##_page_size = __page }; \
-typedef __type __name##_element_t; \
-typedef C_ARRAY_SIZE_TYPE __name##_count_t; \
-typedef struct __name##_t {\
- volatile __name##_count_t count;\
- volatile __name##_count_t size;\
- __name##_element_t * e;\
- __args ;\
-} __name##_t, *__name##_p;
-
-#define C_ARRAY_NULL { 0, 0, NULL }
-
-#define IMPLEMENT_C_ARRAY(__name) \
-static const __name##_t __name##_zero = C_ARRAY_NULL; \
-static C_ARRAY_INLINE \
- void __name##_free(\
- __name##_p a) \
-{\
- if (!a) return;\
- if (a->e) free(a->e);\
- a->count = a->size = 0;\
- a->e = NULL;\
-}\
-static C_ARRAY_INLINE \
- void __name##_clear(\
- __name##_p a) \
-{\
- if (!a) return;\
- a->count = 0;\
-}\
-static C_ARRAY_INLINE \
- void __name##_realloc(\
- __name##_p a, __name##_count_t size) \
-{\
- if (!a || a->size == size) return; \
- if (size == 0) { if (a->e) free(a->e); a->e = NULL; } \
- else a->e = realloc(a->e, size * sizeof(__name##_element_t));\
- a->size = size; \
-}\
-static C_ARRAY_INLINE \
- void __name##_trim(\
- __name##_p a) \
-{\
- if (!a) return;\
- __name##_count_t n = a->count + __name##_page_size;\
- n -= (n % __name##_page_size);\
- if (n != a->size)\
- __name##_realloc(a, n);\
-}\
-static C_ARRAY_INLINE \
- __name##_element_t * __name##_get_ptr(\
- __name##_p a, __name##_count_t index) \
-{\
- if (!a) return NULL;\
- if (index > a->count) index = a->count;\
- return index < a->count ? a->e + index : NULL;\
-}\
-static C_ARRAY_INLINE \
- __name##_count_t __name##_add(\
- __name##_p a, __name##_element_t e) \
-{\
- if (!a) return 0;\
- if (a->count + 1 >= a->size)\
- __name##_realloc(a, a->size + __name##_page_size);\
- a->e[a->count++] = e;\
- return a->count;\
-}\
-static C_ARRAY_INLINE \
- __name##_count_t __name##_insert(\
- __name##_p a, __name##_count_t index, \
- __name##_element_t * e, __name##_count_t count) \
-{\
- if (!a) return 0;\
- if (index > a->count) index = a->count;\
- if (a->count + count >= a->size) \
- __name##_realloc(a, (((a->count + count) / __name##_page_size)+1) * __name##_page_size);\
- if (index < a->count)\
- memmove(&a->e[index + count], &a->e[index], \
- (a->count - index + count) * sizeof(__name##_element_t));\
- memmove(&a->e[index], e, count * sizeof(__name##_element_t));\
- a->count += count;\
- return a->count;\
-}\
-static C_ARRAY_INLINE \
- __name##_count_t __name##_delete(\
- __name##_p a, __name##_count_t index, __name##_count_t count) \
-{\
- if (!a) return 0;\
- if (index > a->count) index = a->count;\
- if (index + count > a->count) \
- count = a->count - index;\
- if (count && a->count - index) { \
- memmove(&a->e[index], &a->e[index + count], \
- (a->count - index - count) * sizeof(__name##_element_t));\
- }\
- a->count -= count;\
- return a->count;\
-}
-
-#endif /* __C_ARRAY_H___ */
+++ /dev/null
-/*
- c_utils.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- libc3 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- libc3 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 libc3. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "c_utils.h"
-
-void
-str_hash_init(str_hash_p h)
-{
- memset(h, 0, sizeof(*h));
-}
-
-void
-str_hash_add(
- str_hash_p h,
- str_p k,
- void * v)
-{
- uint16_t hv = str_hash(k);
- hashval_array_p bin = &h->bin[hv & (STR_HASH_SIZE-1)];
- int inserti = bin->count;
-
- for (int i = 0; i < bin->count; i++)
- if (bin->e[i].key->hash >= hv) {
- inserti = i;
- break;
- }
- str_hashval_t n = { .key = str_dup(k), .val = v };
- hashval_array_insert(bin, inserti, &n, 1);
- return;
-}
-
-void *
-str_hash_lookup(
- str_hash_p h,
- str_p k )
-{
- uint16_t hv = str_hash(k);
- hashval_array_p bin = &h->bin[hv & (STR_HASH_SIZE-1)];
-
- for (int i = 0; i < bin->count; i++) {
- uint16_t h = bin->e[i].key->hash;
- if (h == hv && !str_cmp(k, bin->e[i].key))
- return bin->e[i].val;
- else if (h > hv)
- break;
- }
- return NULL;
-}
+++ /dev/null
-/*
- c_utils.h
-
- Copyright 2008-11 Michel Pollet <buserror@gmail.com>
-
- This program cross examines a root filesystem, loads all the elf
- files it can find, see what other library they load and then
- find the orphans. In then remove the orphans as "user" for it's
- dependencies and continues removing until everything has at least
- one user, OR is a program itself (ie, not a shared library)
-
- cross_linker is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- cross_linker 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 cross_linker. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __C_UTILS_H__
-#define __C_UTILS_H__
-
-#ifndef NO_ALLOCA
-#include <alloca.h>
-#endif
-#include "c_array.h"
-
-/********************************************************************
- * CRC16
- ********************************************************************/
-
-static uint8_t _crc16_lh[16] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
- 0x70, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1 };
-static uint8_t _crc16_ll[16] = { 0x00, 0x21, 0x42, 0x63, 0x84, 0xA5, 0xC6,
- 0xE7, 0x08, 0x29, 0x4A, 0x6B, 0x8C, 0xAD, 0xCE, 0xEF };
-
-static uint16_t crc16_u4(uint16_t crc, uint8_t val)
-{
- uint8_t h = crc >> 8, l = crc & 0xff;
- uint8_t t = (h >> 4) ^ val;
-
- // Shift the CRC Register left 4 bits
- h = (h << 4) | (l >> 4);
- l = l << 4;
- // Do the table lookups and XOR the result into the CRC Tables
- h = h ^ _crc16_lh[t];
- l = l ^ _crc16_ll[t];
- return (h << 8) | l;
-}
-
-static uint16_t crc16_update(uint16_t crc, uint8_t val)
-{
- crc = crc16_u4(crc, val >> 4); // High nibble first
- crc = crc16_u4(crc, val & 0x0F); // Low nibble
- return crc;
-}
-
-static uint16_t crc16_string(char * str)
-{
- uint16_t crc = 0xffff;
- while (*str)
- crc = crc16_update(crc, *str++);
- return crc;
-}
-
-/********************************************************************
- * Hashed strings
- ********************************************************************/
-
-#include <string.h>
-typedef struct str_t {
- uint32_t hash : 16, rom : 1, len : 15;
- char str[0];
-} str_t, *str_p;
-
-static inline str_p str_alloc(size_t len)
-{
- str_p r = (str_p)malloc(sizeof(*r) + len + 1);
- r->rom = r->hash = 0; r->len = len;
- return r;
-}
-static inline str_p str_new_i(const char *s, void * (*_alloc)(size_t))
-{
- int l = s ? strlen(s) : 0;
- str_p r = (str_p)_alloc(sizeof(*r) + l + 1);
- r->hash = 0; r->len = l;
- if (s)
- strcpy(r->str, s);
- return r;
-}
-static inline void str_free(str_p s)
-{
- if (s && !s->rom)
- free(s);
-}
-static inline str_p str_new(const char *s)
-{
- return str_new_i(s, malloc);
-}
-static inline str_p str_dup(const str_p s)
-{
- size_t l = sizeof(*s) + s->len + 1;
- str_p r = (str_p)malloc(l);
- memcpy(r, s, l);
- return r;
-}
-#ifndef NO_ALLOCA
-static inline str_p str_anew(const char *s)
-{
- str_p r = str_new_i(s, alloca);
- r->rom = 1;
- return r;
-}
-static inline str_p str_adup(const str_p s)
-{
- size_t l = sizeof(*s) + s->len + 1;
- str_p r = (str_p)alloca(l);
- memcpy(r, s, l);
- r->rom = 1;
- return r;
-}
-#endif
-static inline uint16_t str_hash(str_p s)
-{
- if (!s->hash) s->hash = crc16_string(s->str);
- return s->hash;
-}
-static inline int str_cmp(str_p s1, str_p s2)
-{
- if (s1 == s2) return 1;
- if (s1->len != s2->len) return 1;
- str_hash(s1);
- str_hash(s2);
- return s1->hash == s2->hash ? strcmp(s1->str, s2->str) : 1;
-}
-
-/********************************************************************
- * Hash table of strings. Key/value pair
- ********************************************************************/
-
-typedef struct str_hashval_t {
- str_p key;
- void * val;
-} str_hashval_t;
-
-DECLARE_C_ARRAY(str_hashval_t, hashval_array, 16);
-IMPLEMENT_C_ARRAY(hashval_array);
-
-#ifndef STR_HASH_SIZE
-#define STR_HASH_SIZE 512 // use 9 bits of the 16 of the CRC
-#endif
-/* uses bins to store the strings as per their hash values */
-typedef struct str_hash_t {
- hashval_array_t bin[STR_HASH_SIZE];
-} str_hash_t, *str_hash_p;
-
-void
-str_hash_init(
- str_hash_p h);
-void
-str_hash_add(
- str_hash_p h,
- str_p k,
- void * v);
-
-void *
-str_hash_lookup(
- str_hash_p h,
- str_p k );
-
-#endif /* __C_UTILS_H__ */
+++ /dev/null
-/*
- c3gl.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of simavr.
-
- simavr is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- simavr 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 simavr. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if __APPLE__
-#define GL_GLEXT_PROTOTYPES
-#include <GLUT/glut.h>
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#else
-#define GL_GLEXT_PROTOTYPES
-#include <GL/gl.h>
-#include <GL/glut.h>
-#include <GL/glext.h>
-#endif
-#include <stdio.h>
-
-
-#include "c3.h"
-#include "c3lines.h"
-#include "c3sphere.h"
-#include "c3light.h"
-#include "c3program.h"
-
-#include "c3driver_context.h"
-
-#include "c3gl.h"
-
-#define GLCHECK(_w) {_w; dumpError(#_w);}
-
-static int dumpError(const char * what)
-{
- GLenum e;
- int count = 0;
- while ((e = glGetError()) != GL_NO_ERROR) {
- printf("%s: %s\n", what, gluErrorString(e));
- count++;
- }
- return count;
-}
-
-int
-c3gl_program_load(
- c3program_p p)
-{
- if (!p || p->pid || p->log)
- return -1;
-
- if (p->verbose)
- printf("%s loading %s\n", __func__, p->name->str);
- for (int si = 0; si < p->shaders.count && !p->log; si++) {
- c3shader_p s = &p->shaders.e[si];
-
- if (p->verbose)
- printf("%s compiling shader %s\n", __func__, s->name->str);
-
- s->sid = (c3apiobject_t)glCreateShader(s->type);
- const GLchar * pgm = s->shader->str;
- glShaderSource((GLuint)s->sid, 1, &pgm, NULL);
-
- glCompileShader((GLuint)s->sid);
-
- GLint status;
- glGetShaderiv((GLuint)s->sid, GL_COMPILE_STATUS, &status);
-
- if (status != GL_FALSE)
- continue;
-
- GLint infoLogLength;
- glGetShaderiv((GLuint)s->sid, GL_INFO_LOG_LENGTH, &infoLogLength);
-
- p->log = str_alloc(infoLogLength);
- glGetShaderInfoLog((GLuint)s->sid, infoLogLength, NULL, p->log->str);
-
- fprintf(stderr, "%s compile %s: %s\n", __func__, s->name->str, p->log->str);
- break;
- }
- if (p->log)
- return -1;
- p->pid = (c3apiobject_t)glCreateProgram();
-
- for (int si = 0; si < p->shaders.count && !p->log; si++) {
- c3shader_p s = &p->shaders.e[si];
-
- glAttachShader((GLuint)p->pid, (GLuint)s->sid);
- }
- glLinkProgram((GLuint)p->pid);
-
- GLint status;
- glGetProgramiv((GLuint)p->pid, GL_LINK_STATUS, &status);
-
- for (int si = 0; si < p->shaders.count && !p->log; si++) {
- c3shader_p s = &p->shaders.e[si];
-
- glDetachShader((GLuint)p->pid, (GLuint)s->sid);
- glDeleteShader((GLuint)s->sid);
- s->sid = 0;
- }
-
- if (status == GL_FALSE) {
- GLint infoLogLength;
- glGetProgramiv((GLuint)p->pid, GL_INFO_LOG_LENGTH, &infoLogLength);
-
- p->log = str_alloc(infoLogLength);
-
- glGetProgramInfoLog((GLuint)p->pid, infoLogLength, NULL, p->log->str);
- fprintf(stderr, "%s link %s: %s\n", __func__, p->name->str, p->log->str);
-
- goto error;
- }
- for (int pi = 0; pi < p->params.count; pi++) {
- c3program_param_p pa = &p->params.e[pi];
- pa->pid = (c3apiobject_t)glGetUniformLocation((GLuint)p->pid, pa->name->str);
- if (pa->pid == (c3apiobject_t)-1) {
- fprintf(stderr, "%s %s: parameter '%s' not found\n",
- __func__, p->name->str, pa->name->str);
- } else
- if (p->verbose)
- printf("%s %s load parameter [%d]'%s'=%d\n", __func__,
- p->name->str, pi, pa->name->str,
- (int)pa->pid);
- }
-
- c3program_purge(p);
- return 0;
-error:
- c3program_purge(p);
- if (p->pid)
- glDeleteProgram((GLuint)p->pid);
- p->pid = 0;
- return -1;
-}
-
-static void
-_c3_load_pixels(
- c3pixels_p pix)
-{
- GLuint mode = pix->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
- if (!pix->texture) {
- if (pix->trace)
- printf("%s Creating texture %s %dx%d\n",
- __func__, pix->name ? pix->name->str : "", pix->w, pix->h);
- pix->dirty = 1;
- GLuint texID = 0;
- GLCHECK(glEnable(mode));
-
- glGenTextures(1, &texID);
-// glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
-// GL_MODULATE); //set texture environment parameters
-// dumpError("glTexEnvf");
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, pix->row / pix->psize);
- GLCHECK(glTexParameteri(mode, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- GLCHECK(glTexParameteri(mode, GL_TEXTURE_MIN_FILTER,
- pix->normalize ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
- GLCHECK(glTexParameteri(mode, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER));
- GLCHECK(glTexParameteri(mode, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER));
- if (pix->normalize)
- GLCHECK(glTexParameteri(mode, GL_GENERATE_MIPMAP, GL_TRUE));
- #if 1
- GLfloat fLargest;
- glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
- //printf("fLargest = %f\n", fLargest);
- GLCHECK(glTexParameterf(mode, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest));
- #endif
- if (pix->normalize)
- GLCHECK(glGenerateMipmap(mode));
-
- pix->texture = (c3apiobject_t)texID;
- pix->dirty = 1;
- }
- if (pix->dirty) {
- pix->dirty = 0;
- GLCHECK(glBindTexture(mode, (GLuint)pix->texture));
- glTexImage2D(mode, 0,
- pix->format == C3PIXEL_A ? GL_ALPHA16 : GL_RGBA8,
- pix->w, pix->h, 0,
- pix->format == C3PIXEL_A ? GL_ALPHA : GL_BGRA,
- GL_UNSIGNED_BYTE,
- pix->base);
- dumpError("glTexImage2D");
- if (pix->normalize)
- GLCHECK(glGenerateMipmap(mode));
- }
-}
-
-static void
-_c3_create_buffer(
- GLuint name,
- GLuint bufferType,
- void * data,
- size_t dataSize,
- GLuint * out)
-{
- GLuint bid;
- glGenBuffers(1, &bid);
-
- GLCHECK(glBindBuffer(GL_ARRAY_BUFFER, bid));
- GLCHECK(glBufferData(GL_ARRAY_BUFFER,
- dataSize,
- data,
- bufferType));
- GLCHECK(glEnableClientState(name));
-}
-
-static void
-_c3_load_vbo(
- c3geometry_p g)
-{
- if (!g->vertice.count)
- return ;
- if (!g->bid) {
- GLuint vao;
- glGenVertexArrays(1, &vao);
- g->bid = (c3apiobject_t)vao;
- }
- glBindVertexArray((GLuint)g->bid);
-
- /*
- * Use 'realloc' on the array as it frees the data, but leaves 'count'
- * unchanged. We neec that for the vertices and the indexes, the others
- * can have a straight free()
- */
- if (!g->vertice.buffer.bid && g->vertice.count) {
- GLuint bid;
-
- _c3_create_buffer(GL_VERTEX_ARRAY,
- g->vertice.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW,
- g->vertice.e, g->vertice.count * sizeof(g->vertice.e[0]),
- &bid);
- glVertexPointer(3, GL_FLOAT, 0, (void*)0);
- g->vertice.buffer.bid = (c3apiobject_t)bid;
- if (!g->vertice.buffer.mutable)
- c3vertex_array_realloc(&g->vertice, 0);
- g->vertice.buffer.dirty = 0;
- }
- if (!g->textures.buffer.bid && g->textures.count) {
- GLuint bid;
-
- _c3_create_buffer(GL_TEXTURE_COORD_ARRAY,
- g->textures.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW,
- g->textures.e, g->textures.count * sizeof(g->textures.e[0]),
- &bid);
- glTexCoordPointer(2, GL_FLOAT, 0, (void*)0);
- g->textures.buffer.bid = (c3apiobject_t)bid;
- if (!g->textures.buffer.mutable)
- c3tex_array_free(&g->textures);
- g->textures.buffer.dirty = 0;
- }
- if (!g->normals.buffer.bid && g->normals.count) {
- GLuint bid;
-
- _c3_create_buffer(GL_NORMAL_ARRAY,
- g->normals.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW,
- g->normals.e, g->normals.count * sizeof(g->normals.e[0]),
- &bid);
- glNormalPointer(GL_FLOAT, 0, (void*) 0);
- g->normals.buffer.bid = (c3apiobject_t)bid;
- if (!g->normals.buffer.mutable)
- c3vertex_array_free(&g->normals);
- g->normals.buffer.dirty = 0;
- }
- if (!g->colorf.buffer.bid && g->colorf.count) {
- GLuint bid;
-
- _c3_create_buffer(GL_COLOR_ARRAY,
- g->colorf.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW,
- g->colorf.e, g->colorf.count * sizeof(g->colorf.e[0]),
- &bid);
- glColorPointer(4, GL_FLOAT, 0, (void*) 0);
- g->colorf.buffer.bid = (c3apiobject_t)bid;
- if (!g->colorf.buffer.mutable)
- c3colorf_array_free(&g->colorf);
- g->colorf.buffer.dirty = 0;
- }
- if (!g->indices.buffer.bid && g->indices.count) {
- GLuint bid;
- glGenBuffers(1, &bid);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bid);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER,
- g->indices.count * sizeof(g->indices.e[0]),
- g->indices.e,
- g->indices.buffer.mutable ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
- g->indices.buffer.bid = (c3apiobject_t)bid;
- if (!g->indices.buffer.mutable)
- c3indices_array_realloc(&g->indices, 0);
- g->indices.buffer.dirty = 0;
- }
-}
-
-static void
-_c3_geometry_project(
- c3context_p c,
- const struct c3driver_context_t * d,
- c3geometry_p g,
- c3mat4p m)
-{
- if (g->mat.texture)
- _c3_load_pixels(g->mat.texture);
- if (g->mat.program)
- c3gl_program_load(g->mat.program);
-
- switch(g->type.type) {
- case C3_SPHERE_TYPE:
- case C3_TRIANGLE_TYPE:
- case C3_LINES_TYPE:
- g->type.subtype = (c3apiobject_t)GL_TRIANGLES;
- break;
- case C3_TEXTURE_TYPE: {
- if (g->mat.texture)
- g->type.subtype = (c3apiobject_t)GL_TRIANGLE_FAN;
- } break;
- case C3_LIGHT_TYPE: {
- c3light_p l = (c3light_p)g;
- GLuint lid = GL_LIGHT0 + (int)l->light_id;
- if (l->color.specular.w > 0)
- glLightfv(lid, GL_SPECULAR, l->color.specular.n);
- if (l->color.ambiant.w > 0)
- glLightfv(lid, GL_AMBIENT, l->color.ambiant.n);
- } break;
- default:
- break;
- }
-
- _c3_load_vbo(g);
-// _c3_update_vbo(g);
-
- glBindVertexArray(0);
- C3_DRIVER_INHERITED(c, d, geometry_project, g, m);
-}
-
-/*
- * This id the meta function that draws a c3geometry. It looks for normals,
- * indices, textures and so on and call the glDrawArrays
- */
-static void
-_c3_geometry_draw(
- c3context_p c,
- const struct c3driver_context_t *d,
- c3geometry_p g )
-{
- c3mat4 eye = c3mat4_mul(
- &g->object->world,
- &c3context_view_get(g->object->context)->cam.mtx);
- glLoadMatrixf(eye.n);
-
- switch(g->type.type) {
- case C3_LIGHT_TYPE: {
- c3light_p l = (c3light_p)g;
- GLuint lid = GL_LIGHT0 + (int)l->light_id;
- glLightfv(lid, GL_POSITION, l->position.n);
- if (c3context_view_get(c)->type != C3_CONTEXT_VIEW_LIGHT)
- glEnable(lid);
- else
- glDisable(lid);
- } break;
- }
- if (!g->bid) {
- C3_DRIVER_INHERITED(c, d, geometry_draw, g);
- return;
- }
- glColor4fv(g->mat.color.n);
- dumpError("glColor");
-
- GLCHECK(glBindVertexArray((GLuint)g->bid));
-
- glDisable(GL_TEXTURE_2D);
- if (g->mat.texture) {
- GLuint mode = g->mat.texture->normalize ?
- GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB;
- glEnable(mode);
- if (g->mat.texture->trace)
- printf("%s uses texture %s (%d tex)\n",
- __func__, g->mat.texture->name->str, g->textures.count);
- // printf("tex mode %d texture %d\n", g->mat.mode, g->mat.texture);
- dumpError("glEnable texture");
- glBindTexture(mode, (GLuint)g->mat.texture->texture);
- dumpError("glBindTexture");
- }
- if (g->mat.program)
- GLCHECK(glUseProgram((GLuint)g->mat.program->pid));
-
- if (g->indices.buffer.bid) {
- GLCHECK(glDrawElements((GLuint)g->type.subtype,
- g->indices.count, GL_UNSIGNED_SHORT,
- (void*)NULL /*g->indices.e*/));
- } else {
- glDrawArrays((GLuint)g->type.subtype, 0, g->vertice.count);
- }
- glBindVertexArray(0);
-
- if (g->mat.texture)
- glDisable(g->mat.texture->normalize ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE_ARB);
- if (g->mat.program)
- glUseProgram(0);
- C3_DRIVER_INHERITED(c, d, geometry_draw, g);
-}
-
-const c3driver_context_t c3context_driver = {
- .geometry_project = _c3_geometry_project,
- .geometry_draw = _c3_geometry_draw,
-};
-
-const struct c3driver_context_t *
-c3gl_getdriver()
-{
- return &c3context_driver;
-}
+++ /dev/null
-/*
- c3gl.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of simavr.
-
- simavr is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- simavr 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 simavr. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3GL_H___
-#define __C3GL_H___
-
-const struct c3driver_context_t *
-c3gl_getdriver();
-
-int
-c3gl_program_load(
- c3program_p p);
-
-#endif /* __C3GL_H___ */
+++ /dev/null
-/*
- c3gl_fbo.c
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- simavr is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- simavr 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 simavr. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if __APPLE__
-#define GL_GLEXT_PROTOTYPES
-#include <GLUT/glut.h>
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#else
-#define GL_GLEXT_PROTOTYPES
-#include <GL/gl.h>
-#include <GL/glut.h>
-#include <GL/glext.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-
-#include "c3gl_fbo.h"
-
-
-#define GLCHECK(_w) {_w; dumpError(#_w);}
-static int dumpError(const char * what)
-{
- GLenum e;
- int count = 0;
- while ((e = glGetError()) != GL_NO_ERROR) {
- printf("%s: %s\n", what, gluErrorString(e));
- count++;
- }
- return count;
-}
-
-int
-c3gl_fbo_create(
- c3gl_fbo_p b,
- c3vec2 size,
- uint32_t flags )
-{
- memset(b, 0, sizeof(*b));
- b->size = size;
- b->flags = flags;
-
- /* Texture */
- GLCHECK(glActiveTexture(GL_TEXTURE0));
-
- if (b->flags & (1 << C3GL_FBO_COLOR)) {
- GLuint tex;
- glGenTextures(1, &tex);
- glBindTexture(GL_TEXTURE_2D, tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- b->size.x, b->size.y, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
- b->buffers[C3GL_FBO_COLOR].bid = (c3apiobject_t)tex;
- }
-
- /* Depth buffer */
- if (b->flags & (1 << C3GL_FBO_DEPTH)) {
- GLuint rbo_depth;
- GLCHECK(glGenRenderbuffers(1, &rbo_depth));
- glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
- GLCHECK(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
- b->size.x, b->size.y));
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
- b->buffers[C3GL_FBO_DEPTH].bid = (c3apiobject_t)rbo_depth;
- }
-
- if (b->flags & (1 << C3GL_FBO_DEPTH_TEX)) {
- GLuint depthTextureId;
- glGenTextures(1, &depthTextureId);
- glBindTexture(GL_TEXTURE_2D, depthTextureId);
-
- // GL_LINEAR does not make sense for depth texture. However, next tutorial shows usage of GL_LINEAR and PCF. Using GL_NEAREST
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- // Remove artefact on the edges of the shadowmap
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
-
- // This is to allow usage of shadow2DProj function in the shader
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
- glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
-
- // No need to force GL_DEPTH_COMPONENT24, drivers usually give you the max precision if available
- glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
- b->size.x, b->size.y,
- 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
- glBindTexture(GL_TEXTURE_2D, 0);
- b->buffers[C3GL_FBO_DEPTH_TEX].bid = (c3apiobject_t)depthTextureId;
- }
-
- /* Framebuffer to link everything together */
- GLuint fbo;
- GLCHECK(glGenFramebuffers(1, &fbo));
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
- if (b->flags & (1 << C3GL_FBO_COLOR)) {
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, (GLuint)b->buffers[C3GL_FBO_COLOR].bid, 0);
- // Set the list of draw buffers.
- GLenum DrawBuffers[2] = { GL_COLOR_ATTACHMENT0 };
- glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
- } else {
- glDrawBuffers(0, NULL); // "1" is the size of DrawBuffers
- glDrawBuffer(GL_NONE);
- glReadBuffer(GL_NONE);
- }
-
- if (b->flags & (1 << C3GL_FBO_DEPTH))
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_RENDERBUFFER, (GLuint)b->buffers[C3GL_FBO_DEPTH].bid);
-
- if (b->flags & (1 << C3GL_FBO_DEPTH_TEX))
- // attach the texture to FBO depth attachment point
- glFramebufferTexture2D(GL_FRAMEBUFFER_EXT,
- GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
- (GLuint)b->buffers[C3GL_FBO_DEPTH_TEX].bid, 0);
-
- b->fbo = (c3apiobject_t)fbo;
-
- GLenum status;
- if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER))
- != GL_FRAMEBUFFER_COMPLETE) {
- fprintf(stderr, "%s: glCheckFramebufferStatus: error %d", __func__, (int)status);
- return -1 ;
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- return 0;
-}
-
-void
-c3gl_fbo_resize(
- c3gl_fbo_p b,
- c3vec2 size)
-{
- b->size = size;
-// Rescale FBO and RBO as well
- if (b->flags & (1 << C3GL_FBO_COLOR)) {
- glBindTexture(GL_TEXTURE_2D, (GLuint)b->buffers[C3GL_FBO_COLOR].bid);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- b->size.x, b->size.y, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-
- if (b->flags & (1 << C3GL_FBO_DEPTH)) {
- glBindRenderbuffer(GL_RENDERBUFFER, (GLuint)b->buffers[C3GL_FBO_DEPTH].bid);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
- b->size.x, b->size.y);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
- }
-}
-
-void
-c3gl_fbo_dispose(
- c3gl_fbo_p b )
-{
- /* free_resources */
- if (b->flags & (1 << C3GL_FBO_DEPTH)) {
- GLuint bid = (GLuint)b->buffers[C3GL_FBO_DEPTH].bid;
- glDeleteRenderbuffers(1, &bid);
- }
- if (b->flags & (1 << C3GL_FBO_COLOR)) {
- GLuint bid = (GLuint)b->buffers[C3GL_FBO_COLOR].bid;
- glDeleteTextures(1, &bid);
- }
- GLuint fbo = (GLuint)b->fbo;
- glDeleteFramebuffers(1, &fbo);
- memset(b, 0, sizeof(*b));
-}
-
+++ /dev/null
-/*
- c3gl_fbo.h
-
- Copyright 2008-2012 Michel Pollet <buserror@gmail.com>
-
- This file is part of libc3.
-
- simavr is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- simavr 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 simavr. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef __C3GL_FBO_H___
-#define __C3GL_FBO_H___
-
-#include "c3types.h"
-
-enum {
- C3GL_FBO_COLOR = 0,
- C3GL_FBO_DEPTH,
- C3GL_FBO_DEPTH_TEX,
- C3GL_FBO_MAX,
-};
-
-typedef struct c3gl_fbo_t {
- c3vec2 size;
- uint32_t flags;
- c3apiobject_t fbo;
- struct {
- c3apiobject_t bid;
- // ... ?
- } buffers[8];
-} c3gl_fbo_t, *c3gl_fbo_p;
-
-
-int
-c3gl_fbo_create(
- c3gl_fbo_p b,
- c3vec2 size,
- uint32_t flags );
-void
-c3gl_fbo_resize(
- c3gl_fbo_p b,
- c3vec2 size);
-void
-c3gl_fbo_dispose(
- c3gl_fbo_p b );
-
-#endif /* __C3GL_FBO_H___ */