3dphotoshoot
changeset 10:c71c477521ca
converting to GLES2 and C++
line diff
1.1 --- a/android/Makefile Mon May 25 05:27:26 2015 +0300 1.2 +++ b/android/Makefile Sun May 31 00:40:26 2015 +0300 1.3 @@ -23,10 +23,12 @@ 1.4 1.5 android_usr = $(NDK)/platforms/$(android_platform)/arch-arm/usr 1.6 android_inc = -I$(native_app_glue_dir) 1.7 -android_libs = -llog -landroid -lEGL -lGLESv1_CM 1.8 +android_libs = -lstdc++ -llog -landroid -lEGL -lGLESv2 1.9 1.10 -CFLAGS = -std=c99 -Wall -g -DAPP_NAME=\"$(name)\" -march=armv7-a -mfloat-abi=softfp \ 1.11 +defs += -DANDROID -DAPP_NAME=\"$(name)\" 1.12 +CXXFLAGS = -Wall -g $(defs) -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 \ 1.13 $(android_inc) -I$(root)/src/android -I$(root)/src/gles $(incpaths) 1.14 +CFLAGS = -std=c99 $(CXXFLAGS) 1.15 LDFLAGS = -Wl,--fix-cortex-a8 -Wl,-z,defs $(android_libs) $(libpaths) -lm 1.16 1.17 .PHONY: debug 1.18 @@ -46,7 +48,7 @@ 1.19 1.20 $(lib): $(obj) 1.21 @mkdir -p libs/armeabi 1.22 - $(CC) -o $@ -shared $(obj) $(LDFLAGS) 1.23 + $(CXX) -o $@ -shared $(obj) $(LDFLAGS) 1.24 1.25 ant_files = *.xml *.properties proguard-project.txt 1.26 ant_dirs = bin libs res obj src gen
2.1 --- a/android/manifest.xml.in Mon May 25 05:27:26 2015 +0300 2.2 +++ b/android/manifest.xml.in Sun May 31 00:40:26 2015 +0300 2.3 @@ -8,6 +8,7 @@ 2.4 2.5 <uses-permission android:name="android.permission.CAMERA" /> 2.6 <uses-feature android:name="android.hardware.camera" /> 2.7 + <uses-feature android:glEsVersion="0x00020000" android:required="true" /> 2.8 2.9 <application android:label="$APPNAME" android:debuggable="true"> 2.10 <!-- android:icon="@drawable/ic_launcher" -->
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/libs/drawtext/COPYING Sun May 31 00:40:26 2015 +0300 3.3 @@ -0,0 +1,674 @@ 3.4 + GNU GENERAL PUBLIC LICENSE 3.5 + Version 3, 29 June 2007 3.6 + 3.7 + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> 3.8 + Everyone is permitted to copy and distribute verbatim copies 3.9 + of this license document, but changing it is not allowed. 3.10 + 3.11 + Preamble 3.12 + 3.13 + The GNU General Public License is a free, copyleft license for 3.14 +software and other kinds of works. 3.15 + 3.16 + The licenses for most software and other practical works are designed 3.17 +to take away your freedom to share and change the works. By contrast, 3.18 +the GNU General Public License is intended to guarantee your freedom to 3.19 +share and change all versions of a program--to make sure it remains free 3.20 +software for all its users. We, the Free Software Foundation, use the 3.21 +GNU General Public License for most of our software; it applies also to 3.22 +any other work released this way by its authors. You can apply it to 3.23 +your programs, too. 3.24 + 3.25 + When we speak of free software, we are referring to freedom, not 3.26 +price. Our General Public Licenses are designed to make sure that you 3.27 +have the freedom to distribute copies of free software (and charge for 3.28 +them if you wish), that you receive source code or can get it if you 3.29 +want it, that you can change the software or use pieces of it in new 3.30 +free programs, and that you know you can do these things. 3.31 + 3.32 + To protect your rights, we need to prevent others from denying you 3.33 +these rights or asking you to surrender the rights. Therefore, you have 3.34 +certain responsibilities if you distribute copies of the software, or if 3.35 +you modify it: responsibilities to respect the freedom of others. 3.36 + 3.37 + For example, if you distribute copies of such a program, whether 3.38 +gratis or for a fee, you must pass on to the recipients the same 3.39 +freedoms that you received. You must make sure that they, too, receive 3.40 +or can get the source code. And you must show them these terms so they 3.41 +know their rights. 3.42 + 3.43 + Developers that use the GNU GPL protect your rights with two steps: 3.44 +(1) assert copyright on the software, and (2) offer you this License 3.45 +giving you legal permission to copy, distribute and/or modify it. 3.46 + 3.47 + For the developers' and authors' protection, the GPL clearly explains 3.48 +that there is no warranty for this free software. For both users' and 3.49 +authors' sake, the GPL requires that modified versions be marked as 3.50 +changed, so that their problems will not be attributed erroneously to 3.51 +authors of previous versions. 3.52 + 3.53 + Some devices are designed to deny users access to install or run 3.54 +modified versions of the software inside them, although the manufacturer 3.55 +can do so. This is fundamentally incompatible with the aim of 3.56 +protecting users' freedom to change the software. The systematic 3.57 +pattern of such abuse occurs in the area of products for individuals to 3.58 +use, which is precisely where it is most unacceptable. Therefore, we 3.59 +have designed this version of the GPL to prohibit the practice for those 3.60 +products. If such problems arise substantially in other domains, we 3.61 +stand ready to extend this provision to those domains in future versions 3.62 +of the GPL, as needed to protect the freedom of users. 3.63 + 3.64 + Finally, every program is threatened constantly by software patents. 3.65 +States should not allow patents to restrict development and use of 3.66 +software on general-purpose computers, but in those that do, we wish to 3.67 +avoid the special danger that patents applied to a free program could 3.68 +make it effectively proprietary. To prevent this, the GPL assures that 3.69 +patents cannot be used to render the program non-free. 3.70 + 3.71 + The precise terms and conditions for copying, distribution and 3.72 +modification follow. 3.73 + 3.74 + TERMS AND CONDITIONS 3.75 + 3.76 + 0. Definitions. 3.77 + 3.78 + "This License" refers to version 3 of the GNU General Public License. 3.79 + 3.80 + "Copyright" also means copyright-like laws that apply to other kinds of 3.81 +works, such as semiconductor masks. 3.82 + 3.83 + "The Program" refers to any copyrightable work licensed under this 3.84 +License. Each licensee is addressed as "you". "Licensees" and 3.85 +"recipients" may be individuals or organizations. 3.86 + 3.87 + To "modify" a work means to copy from or adapt all or part of the work 3.88 +in a fashion requiring copyright permission, other than the making of an 3.89 +exact copy. The resulting work is called a "modified version" of the 3.90 +earlier work or a work "based on" the earlier work. 3.91 + 3.92 + A "covered work" means either the unmodified Program or a work based 3.93 +on the Program. 3.94 + 3.95 + To "propagate" a work means to do anything with it that, without 3.96 +permission, would make you directly or secondarily liable for 3.97 +infringement under applicable copyright law, except executing it on a 3.98 +computer or modifying a private copy. Propagation includes copying, 3.99 +distribution (with or without modification), making available to the 3.100 +public, and in some countries other activities as well. 3.101 + 3.102 + To "convey" a work means any kind of propagation that enables other 3.103 +parties to make or receive copies. Mere interaction with a user through 3.104 +a computer network, with no transfer of a copy, is not conveying. 3.105 + 3.106 + An interactive user interface displays "Appropriate Legal Notices" 3.107 +to the extent that it includes a convenient and prominently visible 3.108 +feature that (1) displays an appropriate copyright notice, and (2) 3.109 +tells the user that there is no warranty for the work (except to the 3.110 +extent that warranties are provided), that licensees may convey the 3.111 +work under this License, and how to view a copy of this License. If 3.112 +the interface presents a list of user commands or options, such as a 3.113 +menu, a prominent item in the list meets this criterion. 3.114 + 3.115 + 1. Source Code. 3.116 + 3.117 + The "source code" for a work means the preferred form of the work 3.118 +for making modifications to it. "Object code" means any non-source 3.119 +form of a work. 3.120 + 3.121 + A "Standard Interface" means an interface that either is an official 3.122 +standard defined by a recognized standards body, or, in the case of 3.123 +interfaces specified for a particular programming language, one that 3.124 +is widely used among developers working in that language. 3.125 + 3.126 + The "System Libraries" of an executable work include anything, other 3.127 +than the work as a whole, that (a) is included in the normal form of 3.128 +packaging a Major Component, but which is not part of that Major 3.129 +Component, and (b) serves only to enable use of the work with that 3.130 +Major Component, or to implement a Standard Interface for which an 3.131 +implementation is available to the public in source code form. A 3.132 +"Major Component", in this context, means a major essential component 3.133 +(kernel, window system, and so on) of the specific operating system 3.134 +(if any) on which the executable work runs, or a compiler used to 3.135 +produce the work, or an object code interpreter used to run it. 3.136 + 3.137 + The "Corresponding Source" for a work in object code form means all 3.138 +the source code needed to generate, install, and (for an executable 3.139 +work) run the object code and to modify the work, including scripts to 3.140 +control those activities. However, it does not include the work's 3.141 +System Libraries, or general-purpose tools or generally available free 3.142 +programs which are used unmodified in performing those activities but 3.143 +which are not part of the work. For example, Corresponding Source 3.144 +includes interface definition files associated with source files for 3.145 +the work, and the source code for shared libraries and dynamically 3.146 +linked subprograms that the work is specifically designed to require, 3.147 +such as by intimate data communication or control flow between those 3.148 +subprograms and other parts of the work. 3.149 + 3.150 + The Corresponding Source need not include anything that users 3.151 +can regenerate automatically from other parts of the Corresponding 3.152 +Source. 3.153 + 3.154 + The Corresponding Source for a work in source code form is that 3.155 +same work. 3.156 + 3.157 + 2. Basic Permissions. 3.158 + 3.159 + All rights granted under this License are granted for the term of 3.160 +copyright on the Program, and are irrevocable provided the stated 3.161 +conditions are met. This License explicitly affirms your unlimited 3.162 +permission to run the unmodified Program. The output from running a 3.163 +covered work is covered by this License only if the output, given its 3.164 +content, constitutes a covered work. This License acknowledges your 3.165 +rights of fair use or other equivalent, as provided by copyright law. 3.166 + 3.167 + You may make, run and propagate covered works that you do not 3.168 +convey, without conditions so long as your license otherwise remains 3.169 +in force. You may convey covered works to others for the sole purpose 3.170 +of having them make modifications exclusively for you, or provide you 3.171 +with facilities for running those works, provided that you comply with 3.172 +the terms of this License in conveying all material for which you do 3.173 +not control copyright. Those thus making or running the covered works 3.174 +for you must do so exclusively on your behalf, under your direction 3.175 +and control, on terms that prohibit them from making any copies of 3.176 +your copyrighted material outside their relationship with you. 3.177 + 3.178 + Conveying under any other circumstances is permitted solely under 3.179 +the conditions stated below. Sublicensing is not allowed; section 10 3.180 +makes it unnecessary. 3.181 + 3.182 + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 3.183 + 3.184 + No covered work shall be deemed part of an effective technological 3.185 +measure under any applicable law fulfilling obligations under article 3.186 +11 of the WIPO copyright treaty adopted on 20 December 1996, or 3.187 +similar laws prohibiting or restricting circumvention of such 3.188 +measures. 3.189 + 3.190 + When you convey a covered work, you waive any legal power to forbid 3.191 +circumvention of technological measures to the extent such circumvention 3.192 +is effected by exercising rights under this License with respect to 3.193 +the covered work, and you disclaim any intention to limit operation or 3.194 +modification of the work as a means of enforcing, against the work's 3.195 +users, your or third parties' legal rights to forbid circumvention of 3.196 +technological measures. 3.197 + 3.198 + 4. Conveying Verbatim Copies. 3.199 + 3.200 + You may convey verbatim copies of the Program's source code as you 3.201 +receive it, in any medium, provided that you conspicuously and 3.202 +appropriately publish on each copy an appropriate copyright notice; 3.203 +keep intact all notices stating that this License and any 3.204 +non-permissive terms added in accord with section 7 apply to the code; 3.205 +keep intact all notices of the absence of any warranty; and give all 3.206 +recipients a copy of this License along with the Program. 3.207 + 3.208 + You may charge any price or no price for each copy that you convey, 3.209 +and you may offer support or warranty protection for a fee. 3.210 + 3.211 + 5. Conveying Modified Source Versions. 3.212 + 3.213 + You may convey a work based on the Program, or the modifications to 3.214 +produce it from the Program, in the form of source code under the 3.215 +terms of section 4, provided that you also meet all of these conditions: 3.216 + 3.217 + a) The work must carry prominent notices stating that you modified 3.218 + it, and giving a relevant date. 3.219 + 3.220 + b) The work must carry prominent notices stating that it is 3.221 + released under this License and any conditions added under section 3.222 + 7. This requirement modifies the requirement in section 4 to 3.223 + "keep intact all notices". 3.224 + 3.225 + c) You must license the entire work, as a whole, under this 3.226 + License to anyone who comes into possession of a copy. This 3.227 + License will therefore apply, along with any applicable section 7 3.228 + additional terms, to the whole of the work, and all its parts, 3.229 + regardless of how they are packaged. This License gives no 3.230 + permission to license the work in any other way, but it does not 3.231 + invalidate such permission if you have separately received it. 3.232 + 3.233 + d) If the work has interactive user interfaces, each must display 3.234 + Appropriate Legal Notices; however, if the Program has interactive 3.235 + interfaces that do not display Appropriate Legal Notices, your 3.236 + work need not make them do so. 3.237 + 3.238 + A compilation of a covered work with other separate and independent 3.239 +works, which are not by their nature extensions of the covered work, 3.240 +and which are not combined with it such as to form a larger program, 3.241 +in or on a volume of a storage or distribution medium, is called an 3.242 +"aggregate" if the compilation and its resulting copyright are not 3.243 +used to limit the access or legal rights of the compilation's users 3.244 +beyond what the individual works permit. Inclusion of a covered work 3.245 +in an aggregate does not cause this License to apply to the other 3.246 +parts of the aggregate. 3.247 + 3.248 + 6. Conveying Non-Source Forms. 3.249 + 3.250 + You may convey a covered work in object code form under the terms 3.251 +of sections 4 and 5, provided that you also convey the 3.252 +machine-readable Corresponding Source under the terms of this License, 3.253 +in one of these ways: 3.254 + 3.255 + a) Convey the object code in, or embodied in, a physical product 3.256 + (including a physical distribution medium), accompanied by the 3.257 + Corresponding Source fixed on a durable physical medium 3.258 + customarily used for software interchange. 3.259 + 3.260 + b) Convey the object code in, or embodied in, a physical product 3.261 + (including a physical distribution medium), accompanied by a 3.262 + written offer, valid for at least three years and valid for as 3.263 + long as you offer spare parts or customer support for that product 3.264 + model, to give anyone who possesses the object code either (1) a 3.265 + copy of the Corresponding Source for all the software in the 3.266 + product that is covered by this License, on a durable physical 3.267 + medium customarily used for software interchange, for a price no 3.268 + more than your reasonable cost of physically performing this 3.269 + conveying of source, or (2) access to copy the 3.270 + Corresponding Source from a network server at no charge. 3.271 + 3.272 + c) Convey individual copies of the object code with a copy of the 3.273 + written offer to provide the Corresponding Source. This 3.274 + alternative is allowed only occasionally and noncommercially, and 3.275 + only if you received the object code with such an offer, in accord 3.276 + with subsection 6b. 3.277 + 3.278 + d) Convey the object code by offering access from a designated 3.279 + place (gratis or for a charge), and offer equivalent access to the 3.280 + Corresponding Source in the same way through the same place at no 3.281 + further charge. You need not require recipients to copy the 3.282 + Corresponding Source along with the object code. If the place to 3.283 + copy the object code is a network server, the Corresponding Source 3.284 + may be on a different server (operated by you or a third party) 3.285 + that supports equivalent copying facilities, provided you maintain 3.286 + clear directions next to the object code saying where to find the 3.287 + Corresponding Source. Regardless of what server hosts the 3.288 + Corresponding Source, you remain obligated to ensure that it is 3.289 + available for as long as needed to satisfy these requirements. 3.290 + 3.291 + e) Convey the object code using peer-to-peer transmission, provided 3.292 + you inform other peers where the object code and Corresponding 3.293 + Source of the work are being offered to the general public at no 3.294 + charge under subsection 6d. 3.295 + 3.296 + A separable portion of the object code, whose source code is excluded 3.297 +from the Corresponding Source as a System Library, need not be 3.298 +included in conveying the object code work. 3.299 + 3.300 + A "User Product" is either (1) a "consumer product", which means any 3.301 +tangible personal property which is normally used for personal, family, 3.302 +or household purposes, or (2) anything designed or sold for incorporation 3.303 +into a dwelling. In determining whether a product is a consumer product, 3.304 +doubtful cases shall be resolved in favor of coverage. For a particular 3.305 +product received by a particular user, "normally used" refers to a 3.306 +typical or common use of that class of product, regardless of the status 3.307 +of the particular user or of the way in which the particular user 3.308 +actually uses, or expects or is expected to use, the product. A product 3.309 +is a consumer product regardless of whether the product has substantial 3.310 +commercial, industrial or non-consumer uses, unless such uses represent 3.311 +the only significant mode of use of the product. 3.312 + 3.313 + "Installation Information" for a User Product means any methods, 3.314 +procedures, authorization keys, or other information required to install 3.315 +and execute modified versions of a covered work in that User Product from 3.316 +a modified version of its Corresponding Source. The information must 3.317 +suffice to ensure that the continued functioning of the modified object 3.318 +code is in no case prevented or interfered with solely because 3.319 +modification has been made. 3.320 + 3.321 + If you convey an object code work under this section in, or with, or 3.322 +specifically for use in, a User Product, and the conveying occurs as 3.323 +part of a transaction in which the right of possession and use of the 3.324 +User Product is transferred to the recipient in perpetuity or for a 3.325 +fixed term (regardless of how the transaction is characterized), the 3.326 +Corresponding Source conveyed under this section must be accompanied 3.327 +by the Installation Information. But this requirement does not apply 3.328 +if neither you nor any third party retains the ability to install 3.329 +modified object code on the User Product (for example, the work has 3.330 +been installed in ROM). 3.331 + 3.332 + The requirement to provide Installation Information does not include a 3.333 +requirement to continue to provide support service, warranty, or updates 3.334 +for a work that has been modified or installed by the recipient, or for 3.335 +the User Product in which it has been modified or installed. Access to a 3.336 +network may be denied when the modification itself materially and 3.337 +adversely affects the operation of the network or violates the rules and 3.338 +protocols for communication across the network. 3.339 + 3.340 + Corresponding Source conveyed, and Installation Information provided, 3.341 +in accord with this section must be in a format that is publicly 3.342 +documented (and with an implementation available to the public in 3.343 +source code form), and must require no special password or key for 3.344 +unpacking, reading or copying. 3.345 + 3.346 + 7. Additional Terms. 3.347 + 3.348 + "Additional permissions" are terms that supplement the terms of this 3.349 +License by making exceptions from one or more of its conditions. 3.350 +Additional permissions that are applicable to the entire Program shall 3.351 +be treated as though they were included in this License, to the extent 3.352 +that they are valid under applicable law. If additional permissions 3.353 +apply only to part of the Program, that part may be used separately 3.354 +under those permissions, but the entire Program remains governed by 3.355 +this License without regard to the additional permissions. 3.356 + 3.357 + When you convey a copy of a covered work, you may at your option 3.358 +remove any additional permissions from that copy, or from any part of 3.359 +it. (Additional permissions may be written to require their own 3.360 +removal in certain cases when you modify the work.) You may place 3.361 +additional permissions on material, added by you to a covered work, 3.362 +for which you have or can give appropriate copyright permission. 3.363 + 3.364 + Notwithstanding any other provision of this License, for material you 3.365 +add to a covered work, you may (if authorized by the copyright holders of 3.366 +that material) supplement the terms of this License with terms: 3.367 + 3.368 + a) Disclaiming warranty or limiting liability differently from the 3.369 + terms of sections 15 and 16 of this License; or 3.370 + 3.371 + b) Requiring preservation of specified reasonable legal notices or 3.372 + author attributions in that material or in the Appropriate Legal 3.373 + Notices displayed by works containing it; or 3.374 + 3.375 + c) Prohibiting misrepresentation of the origin of that material, or 3.376 + requiring that modified versions of such material be marked in 3.377 + reasonable ways as different from the original version; or 3.378 + 3.379 + d) Limiting the use for publicity purposes of names of licensors or 3.380 + authors of the material; or 3.381 + 3.382 + e) Declining to grant rights under trademark law for use of some 3.383 + trade names, trademarks, or service marks; or 3.384 + 3.385 + f) Requiring indemnification of licensors and authors of that 3.386 + material by anyone who conveys the material (or modified versions of 3.387 + it) with contractual assumptions of liability to the recipient, for 3.388 + any liability that these contractual assumptions directly impose on 3.389 + those licensors and authors. 3.390 + 3.391 + All other non-permissive additional terms are considered "further 3.392 +restrictions" within the meaning of section 10. If the Program as you 3.393 +received it, or any part of it, contains a notice stating that it is 3.394 +governed by this License along with a term that is a further 3.395 +restriction, you may remove that term. If a license document contains 3.396 +a further restriction but permits relicensing or conveying under this 3.397 +License, you may add to a covered work material governed by the terms 3.398 +of that license document, provided that the further restriction does 3.399 +not survive such relicensing or conveying. 3.400 + 3.401 + If you add terms to a covered work in accord with this section, you 3.402 +must place, in the relevant source files, a statement of the 3.403 +additional terms that apply to those files, or a notice indicating 3.404 +where to find the applicable terms. 3.405 + 3.406 + Additional terms, permissive or non-permissive, may be stated in the 3.407 +form of a separately written license, or stated as exceptions; 3.408 +the above requirements apply either way. 3.409 + 3.410 + 8. Termination. 3.411 + 3.412 + You may not propagate or modify a covered work except as expressly 3.413 +provided under this License. Any attempt otherwise to propagate or 3.414 +modify it is void, and will automatically terminate your rights under 3.415 +this License (including any patent licenses granted under the third 3.416 +paragraph of section 11). 3.417 + 3.418 + However, if you cease all violation of this License, then your 3.419 +license from a particular copyright holder is reinstated (a) 3.420 +provisionally, unless and until the copyright holder explicitly and 3.421 +finally terminates your license, and (b) permanently, if the copyright 3.422 +holder fails to notify you of the violation by some reasonable means 3.423 +prior to 60 days after the cessation. 3.424 + 3.425 + Moreover, your license from a particular copyright holder is 3.426 +reinstated permanently if the copyright holder notifies you of the 3.427 +violation by some reasonable means, this is the first time you have 3.428 +received notice of violation of this License (for any work) from that 3.429 +copyright holder, and you cure the violation prior to 30 days after 3.430 +your receipt of the notice. 3.431 + 3.432 + Termination of your rights under this section does not terminate the 3.433 +licenses of parties who have received copies or rights from you under 3.434 +this License. If your rights have been terminated and not permanently 3.435 +reinstated, you do not qualify to receive new licenses for the same 3.436 +material under section 10. 3.437 + 3.438 + 9. Acceptance Not Required for Having Copies. 3.439 + 3.440 + You are not required to accept this License in order to receive or 3.441 +run a copy of the Program. Ancillary propagation of a covered work 3.442 +occurring solely as a consequence of using peer-to-peer transmission 3.443 +to receive a copy likewise does not require acceptance. However, 3.444 +nothing other than this License grants you permission to propagate or 3.445 +modify any covered work. These actions infringe copyright if you do 3.446 +not accept this License. Therefore, by modifying or propagating a 3.447 +covered work, you indicate your acceptance of this License to do so. 3.448 + 3.449 + 10. Automatic Licensing of Downstream Recipients. 3.450 + 3.451 + Each time you convey a covered work, the recipient automatically 3.452 +receives a license from the original licensors, to run, modify and 3.453 +propagate that work, subject to this License. You are not responsible 3.454 +for enforcing compliance by third parties with this License. 3.455 + 3.456 + An "entity transaction" is a transaction transferring control of an 3.457 +organization, or substantially all assets of one, or subdividing an 3.458 +organization, or merging organizations. If propagation of a covered 3.459 +work results from an entity transaction, each party to that 3.460 +transaction who receives a copy of the work also receives whatever 3.461 +licenses to the work the party's predecessor in interest had or could 3.462 +give under the previous paragraph, plus a right to possession of the 3.463 +Corresponding Source of the work from the predecessor in interest, if 3.464 +the predecessor has it or can get it with reasonable efforts. 3.465 + 3.466 + You may not impose any further restrictions on the exercise of the 3.467 +rights granted or affirmed under this License. For example, you may 3.468 +not impose a license fee, royalty, or other charge for exercise of 3.469 +rights granted under this License, and you may not initiate litigation 3.470 +(including a cross-claim or counterclaim in a lawsuit) alleging that 3.471 +any patent claim is infringed by making, using, selling, offering for 3.472 +sale, or importing the Program or any portion of it. 3.473 + 3.474 + 11. Patents. 3.475 + 3.476 + A "contributor" is a copyright holder who authorizes use under this 3.477 +License of the Program or a work on which the Program is based. The 3.478 +work thus licensed is called the contributor's "contributor version". 3.479 + 3.480 + A contributor's "essential patent claims" are all patent claims 3.481 +owned or controlled by the contributor, whether already acquired or 3.482 +hereafter acquired, that would be infringed by some manner, permitted 3.483 +by this License, of making, using, or selling its contributor version, 3.484 +but do not include claims that would be infringed only as a 3.485 +consequence of further modification of the contributor version. For 3.486 +purposes of this definition, "control" includes the right to grant 3.487 +patent sublicenses in a manner consistent with the requirements of 3.488 +this License. 3.489 + 3.490 + Each contributor grants you a non-exclusive, worldwide, royalty-free 3.491 +patent license under the contributor's essential patent claims, to 3.492 +make, use, sell, offer for sale, import and otherwise run, modify and 3.493 +propagate the contents of its contributor version. 3.494 + 3.495 + In the following three paragraphs, a "patent license" is any express 3.496 +agreement or commitment, however denominated, not to enforce a patent 3.497 +(such as an express permission to practice a patent or covenant not to 3.498 +sue for patent infringement). To "grant" such a patent license to a 3.499 +party means to make such an agreement or commitment not to enforce a 3.500 +patent against the party. 3.501 + 3.502 + If you convey a covered work, knowingly relying on a patent license, 3.503 +and the Corresponding Source of the work is not available for anyone 3.504 +to copy, free of charge and under the terms of this License, through a 3.505 +publicly available network server or other readily accessible means, 3.506 +then you must either (1) cause the Corresponding Source to be so 3.507 +available, or (2) arrange to deprive yourself of the benefit of the 3.508 +patent license for this particular work, or (3) arrange, in a manner 3.509 +consistent with the requirements of this License, to extend the patent 3.510 +license to downstream recipients. "Knowingly relying" means you have 3.511 +actual knowledge that, but for the patent license, your conveying the 3.512 +covered work in a country, or your recipient's use of the covered work 3.513 +in a country, would infringe one or more identifiable patents in that 3.514 +country that you have reason to believe are valid. 3.515 + 3.516 + If, pursuant to or in connection with a single transaction or 3.517 +arrangement, you convey, or propagate by procuring conveyance of, a 3.518 +covered work, and grant a patent license to some of the parties 3.519 +receiving the covered work authorizing them to use, propagate, modify 3.520 +or convey a specific copy of the covered work, then the patent license 3.521 +you grant is automatically extended to all recipients of the covered 3.522 +work and works based on it. 3.523 + 3.524 + A patent license is "discriminatory" if it does not include within 3.525 +the scope of its coverage, prohibits the exercise of, or is 3.526 +conditioned on the non-exercise of one or more of the rights that are 3.527 +specifically granted under this License. You may not convey a covered 3.528 +work if you are a party to an arrangement with a third party that is 3.529 +in the business of distributing software, under which you make payment 3.530 +to the third party based on the extent of your activity of conveying 3.531 +the work, and under which the third party grants, to any of the 3.532 +parties who would receive the covered work from you, a discriminatory 3.533 +patent license (a) in connection with copies of the covered work 3.534 +conveyed by you (or copies made from those copies), or (b) primarily 3.535 +for and in connection with specific products or compilations that 3.536 +contain the covered work, unless you entered into that arrangement, 3.537 +or that patent license was granted, prior to 28 March 2007. 3.538 + 3.539 + Nothing in this License shall be construed as excluding or limiting 3.540 +any implied license or other defenses to infringement that may 3.541 +otherwise be available to you under applicable patent law. 3.542 + 3.543 + 12. No Surrender of Others' Freedom. 3.544 + 3.545 + If conditions are imposed on you (whether by court order, agreement or 3.546 +otherwise) that contradict the conditions of this License, they do not 3.547 +excuse you from the conditions of this License. If you cannot convey a 3.548 +covered work so as to satisfy simultaneously your obligations under this 3.549 +License and any other pertinent obligations, then as a consequence you may 3.550 +not convey it at all. For example, if you agree to terms that obligate you 3.551 +to collect a royalty for further conveying from those to whom you convey 3.552 +the Program, the only way you could satisfy both those terms and this 3.553 +License would be to refrain entirely from conveying the Program. 3.554 + 3.555 + 13. Use with the GNU Affero General Public License. 3.556 + 3.557 + Notwithstanding any other provision of this License, you have 3.558 +permission to link or combine any covered work with a work licensed 3.559 +under version 3 of the GNU Affero General Public License into a single 3.560 +combined work, and to convey the resulting work. The terms of this 3.561 +License will continue to apply to the part which is the covered work, 3.562 +but the special requirements of the GNU Affero General Public License, 3.563 +section 13, concerning interaction through a network will apply to the 3.564 +combination as such. 3.565 + 3.566 + 14. Revised Versions of this License. 3.567 + 3.568 + The Free Software Foundation may publish revised and/or new versions of 3.569 +the GNU General Public License from time to time. Such new versions will 3.570 +be similar in spirit to the present version, but may differ in detail to 3.571 +address new problems or concerns. 3.572 + 3.573 + Each version is given a distinguishing version number. If the 3.574 +Program specifies that a certain numbered version of the GNU General 3.575 +Public License "or any later version" applies to it, you have the 3.576 +option of following the terms and conditions either of that numbered 3.577 +version or of any later version published by the Free Software 3.578 +Foundation. If the Program does not specify a version number of the 3.579 +GNU General Public License, you may choose any version ever published 3.580 +by the Free Software Foundation. 3.581 + 3.582 + If the Program specifies that a proxy can decide which future 3.583 +versions of the GNU General Public License can be used, that proxy's 3.584 +public statement of acceptance of a version permanently authorizes you 3.585 +to choose that version for the Program. 3.586 + 3.587 + Later license versions may give you additional or different 3.588 +permissions. However, no additional obligations are imposed on any 3.589 +author or copyright holder as a result of your choosing to follow a 3.590 +later version. 3.591 + 3.592 + 15. Disclaimer of Warranty. 3.593 + 3.594 + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 3.595 +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 3.596 +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 3.597 +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 3.598 +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 3.599 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 3.600 +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 3.601 +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 3.602 + 3.603 + 16. Limitation of Liability. 3.604 + 3.605 + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 3.606 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 3.607 +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 3.608 +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 3.609 +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 3.610 +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 3.611 +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 3.612 +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 3.613 +SUCH DAMAGES. 3.614 + 3.615 + 17. Interpretation of Sections 15 and 16. 3.616 + 3.617 + If the disclaimer of warranty and limitation of liability provided 3.618 +above cannot be given local legal effect according to their terms, 3.619 +reviewing courts shall apply local law that most closely approximates 3.620 +an absolute waiver of all civil liability in connection with the 3.621 +Program, unless a warranty or assumption of liability accompanies a 3.622 +copy of the Program in return for a fee. 3.623 + 3.624 + END OF TERMS AND CONDITIONS 3.625 + 3.626 + How to Apply These Terms to Your New Programs 3.627 + 3.628 + If you develop a new program, and you want it to be of the greatest 3.629 +possible use to the public, the best way to achieve this is to make it 3.630 +free software which everyone can redistribute and change under these terms. 3.631 + 3.632 + To do so, attach the following notices to the program. It is safest 3.633 +to attach them to the start of each source file to most effectively 3.634 +state the exclusion of warranty; and each file should have at least 3.635 +the "copyright" line and a pointer to where the full notice is found. 3.636 + 3.637 + <one line to give the program's name and a brief idea of what it does.> 3.638 + Copyright (C) <year> <name of author> 3.639 + 3.640 + This program is free software: you can redistribute it and/or modify 3.641 + it under the terms of the GNU General Public License as published by 3.642 + the Free Software Foundation, either version 3 of the License, or 3.643 + (at your option) any later version. 3.644 + 3.645 + This program is distributed in the hope that it will be useful, 3.646 + but WITHOUT ANY WARRANTY; without even the implied warranty of 3.647 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3.648 + GNU General Public License for more details. 3.649 + 3.650 + You should have received a copy of the GNU General Public License 3.651 + along with this program. If not, see <http://www.gnu.org/licenses/>. 3.652 + 3.653 +Also add information on how to contact you by electronic and paper mail. 3.654 + 3.655 + If the program does terminal interaction, make it output a short 3.656 +notice like this when it starts in an interactive mode: 3.657 + 3.658 + <program> Copyright (C) <year> <name of author> 3.659 + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 3.660 + This is free software, and you are welcome to redistribute it 3.661 + under certain conditions; type `show c' for details. 3.662 + 3.663 +The hypothetical commands `show w' and `show c' should show the appropriate 3.664 +parts of the General Public License. Of course, your program's commands 3.665 +might be different; for a GUI interface, you would use an "about box". 3.666 + 3.667 + You should also get your employer (if you work as a programmer) or school, 3.668 +if any, to sign a "copyright disclaimer" for the program, if necessary. 3.669 +For more information on this, and how to apply and follow the GNU GPL, see 3.670 +<http://www.gnu.org/licenses/>. 3.671 + 3.672 + The GNU General Public License does not permit incorporating your program 3.673 +into proprietary programs. If your program is a subroutine library, you 3.674 +may consider it more useful to permit linking proprietary applications with 3.675 +the library. If this is what you want to do, use the GNU Lesser General 3.676 +Public License instead of this License. But first, please read 3.677 +<http://www.gnu.org/philosophy/why-not-lgpl.html>.
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/libs/drawtext/COPYING.LESSER Sun May 31 00:40:26 2015 +0300 4.3 @@ -0,0 +1,165 @@ 4.4 + GNU LESSER GENERAL PUBLIC LICENSE 4.5 + Version 3, 29 June 2007 4.6 + 4.7 + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> 4.8 + Everyone is permitted to copy and distribute verbatim copies 4.9 + of this license document, but changing it is not allowed. 4.10 + 4.11 + 4.12 + This version of the GNU Lesser General Public License incorporates 4.13 +the terms and conditions of version 3 of the GNU General Public 4.14 +License, supplemented by the additional permissions listed below. 4.15 + 4.16 + 0. Additional Definitions. 4.17 + 4.18 + As used herein, "this License" refers to version 3 of the GNU Lesser 4.19 +General Public License, and the "GNU GPL" refers to version 3 of the GNU 4.20 +General Public License. 4.21 + 4.22 + "The Library" refers to a covered work governed by this License, 4.23 +other than an Application or a Combined Work as defined below. 4.24 + 4.25 + An "Application" is any work that makes use of an interface provided 4.26 +by the Library, but which is not otherwise based on the Library. 4.27 +Defining a subclass of a class defined by the Library is deemed a mode 4.28 +of using an interface provided by the Library. 4.29 + 4.30 + A "Combined Work" is a work produced by combining or linking an 4.31 +Application with the Library. The particular version of the Library 4.32 +with which the Combined Work was made is also called the "Linked 4.33 +Version". 4.34 + 4.35 + The "Minimal Corresponding Source" for a Combined Work means the 4.36 +Corresponding Source for the Combined Work, excluding any source code 4.37 +for portions of the Combined Work that, considered in isolation, are 4.38 +based on the Application, and not on the Linked Version. 4.39 + 4.40 + The "Corresponding Application Code" for a Combined Work means the 4.41 +object code and/or source code for the Application, including any data 4.42 +and utility programs needed for reproducing the Combined Work from the 4.43 +Application, but excluding the System Libraries of the Combined Work. 4.44 + 4.45 + 1. Exception to Section 3 of the GNU GPL. 4.46 + 4.47 + You may convey a covered work under sections 3 and 4 of this License 4.48 +without being bound by section 3 of the GNU GPL. 4.49 + 4.50 + 2. Conveying Modified Versions. 4.51 + 4.52 + If you modify a copy of the Library, and, in your modifications, a 4.53 +facility refers to a function or data to be supplied by an Application 4.54 +that uses the facility (other than as an argument passed when the 4.55 +facility is invoked), then you may convey a copy of the modified 4.56 +version: 4.57 + 4.58 + a) under this License, provided that you make a good faith effort to 4.59 + ensure that, in the event an Application does not supply the 4.60 + function or data, the facility still operates, and performs 4.61 + whatever part of its purpose remains meaningful, or 4.62 + 4.63 + b) under the GNU GPL, with none of the additional permissions of 4.64 + this License applicable to that copy. 4.65 + 4.66 + 3. Object Code Incorporating Material from Library Header Files. 4.67 + 4.68 + The object code form of an Application may incorporate material from 4.69 +a header file that is part of the Library. You may convey such object 4.70 +code under terms of your choice, provided that, if the incorporated 4.71 +material is not limited to numerical parameters, data structure 4.72 +layouts and accessors, or small macros, inline functions and templates 4.73 +(ten or fewer lines in length), you do both of the following: 4.74 + 4.75 + a) Give prominent notice with each copy of the object code that the 4.76 + Library is used in it and that the Library and its use are 4.77 + covered by this License. 4.78 + 4.79 + b) Accompany the object code with a copy of the GNU GPL and this license 4.80 + document. 4.81 + 4.82 + 4. Combined Works. 4.83 + 4.84 + You may convey a Combined Work under terms of your choice that, 4.85 +taken together, effectively do not restrict modification of the 4.86 +portions of the Library contained in the Combined Work and reverse 4.87 +engineering for debugging such modifications, if you also do each of 4.88 +the following: 4.89 + 4.90 + a) Give prominent notice with each copy of the Combined Work that 4.91 + the Library is used in it and that the Library and its use are 4.92 + covered by this License. 4.93 + 4.94 + b) Accompany the Combined Work with a copy of the GNU GPL and this license 4.95 + document. 4.96 + 4.97 + c) For a Combined Work that displays copyright notices during 4.98 + execution, include the copyright notice for the Library among 4.99 + these notices, as well as a reference directing the user to the 4.100 + copies of the GNU GPL and this license document. 4.101 + 4.102 + d) Do one of the following: 4.103 + 4.104 + 0) Convey the Minimal Corresponding Source under the terms of this 4.105 + License, and the Corresponding Application Code in a form 4.106 + suitable for, and under terms that permit, the user to 4.107 + recombine or relink the Application with a modified version of 4.108 + the Linked Version to produce a modified Combined Work, in the 4.109 + manner specified by section 6 of the GNU GPL for conveying 4.110 + Corresponding Source. 4.111 + 4.112 + 1) Use a suitable shared library mechanism for linking with the 4.113 + Library. A suitable mechanism is one that (a) uses at run time 4.114 + a copy of the Library already present on the user's computer 4.115 + system, and (b) will operate properly with a modified version 4.116 + of the Library that is interface-compatible with the Linked 4.117 + Version. 4.118 + 4.119 + e) Provide Installation Information, but only if you would otherwise 4.120 + be required to provide such information under section 6 of the 4.121 + GNU GPL, and only to the extent that such information is 4.122 + necessary to install and execute a modified version of the 4.123 + Combined Work produced by recombining or relinking the 4.124 + Application with a modified version of the Linked Version. (If 4.125 + you use option 4d0, the Installation Information must accompany 4.126 + the Minimal Corresponding Source and Corresponding Application 4.127 + Code. If you use option 4d1, you must provide the Installation 4.128 + Information in the manner specified by section 6 of the GNU GPL 4.129 + for conveying Corresponding Source.) 4.130 + 4.131 + 5. Combined Libraries. 4.132 + 4.133 + You may place library facilities that are a work based on the 4.134 +Library side by side in a single library together with other library 4.135 +facilities that are not Applications and are not covered by this 4.136 +License, and convey such a combined library under terms of your 4.137 +choice, if you do both of the following: 4.138 + 4.139 + a) Accompany the combined library with a copy of the same work based 4.140 + on the Library, uncombined with any other library facilities, 4.141 + conveyed under the terms of this License. 4.142 + 4.143 + b) Give prominent notice with the combined library that part of it 4.144 + is a work based on the Library, and explaining where to find the 4.145 + accompanying uncombined form of the same work. 4.146 + 4.147 + 6. Revised Versions of the GNU Lesser General Public License. 4.148 + 4.149 + The Free Software Foundation may publish revised and/or new versions 4.150 +of the GNU Lesser General Public License from time to time. Such new 4.151 +versions will be similar in spirit to the present version, but may 4.152 +differ in detail to address new problems or concerns. 4.153 + 4.154 + Each version is given a distinguishing version number. If the 4.155 +Library as you received it specifies that a certain numbered version 4.156 +of the GNU Lesser General Public License "or any later version" 4.157 +applies to it, you have the option of following the terms and 4.158 +conditions either of that published version or of any later version 4.159 +published by the Free Software Foundation. If the Library as you 4.160 +received it does not specify a version number of the GNU Lesser 4.161 +General Public License, you may choose any version of the GNU Lesser 4.162 +General Public License ever published by the Free Software Foundation. 4.163 + 4.164 + If the Library as you received it specifies that a proxy can decide 4.165 +whether future versions of the GNU Lesser General Public License shall 4.166 +apply, that proxy's public statement of acceptance of any version is 4.167 +permanent authorization for you to choose that version for the 4.168 +Library.
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/libs/drawtext/README Sun May 31 00:40:26 2015 +0300 5.3 @@ -0,0 +1,19 @@ 5.4 +libdrawtext - 0.2.1 5.5 +------------------- 5.6 + 5.7 +Libdrawtext is a simple library for fast anti-aliased text rendering in OpenGL. 5.8 + 5.9 +Copyright (C) 2011-2014 John Tsiombikas <nuclear@member.fsf.org> 5.10 +You may freely use, modify and/or redistribute libdrawtext, under the terms of 5.11 +the GNU Lesser General Public License (LGPL) version 3 (or at your option, any 5.12 +later version published by the Free Software Foundation). See COPYING, and 5.13 +COPYING.LESSER for details. 5.14 + 5.15 +website: http://nuclear.mutantstargoat.com/sw/libdrawtext 5.16 + 5.17 +master repository (hg): http://nuclear.mutantstargoat.com/hg/libdrawtext 5.18 +mirror repository (git): https://github.com/jtsiomb/libdrawtext.git 5.19 + 5.20 +Feel free to send in bug reports, patches, and other comments to 5.21 +nuclear@member.fsf.org 5.22 +Only plain text email messages, hard-wrapped at 72 columns will be accepted.
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/libs/drawtext/drawgl.c Sun May 31 00:40:26 2015 +0300 6.3 @@ -0,0 +1,302 @@ 6.4 +/* 6.5 +libdrawtext - a simple library for fast text rendering in OpenGL 6.6 +Copyright (C) 2011-2012 John Tsiombikas <nuclear@member.fsf.org> 6.7 + 6.8 +This program is free software: you can redistribute it and/or modify 6.9 +it under the terms of the GNU Lesser General Public License as published by 6.10 +the Free Software Foundation, either version 3 of the License, or 6.11 +(at your option) any later version. 6.12 + 6.13 +This program is distributed in the hope that it will be useful, 6.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 6.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 6.16 +GNU Lesser General Public License for more details. 6.17 + 6.18 +You should have received a copy of the GNU Lesser General Public License 6.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 6.20 +*/ 6.21 +#ifndef NO_OPENGL 6.22 +#include <stdarg.h> 6.23 +#include <math.h> 6.24 +#include <ctype.h> 6.25 + 6.26 +#include <stdlib.h> 6.27 + 6.28 +#ifndef _MSC_VER 6.29 +#include <alloca.h> 6.30 +#else 6.31 +#include <malloc.h> 6.32 +#endif 6.33 + 6.34 +#ifdef TARGET_IPHONE 6.35 +#include <OpenGLES/ES2/gl.h> 6.36 +#define GL_ES 6.37 +#elif defined(ANDROID) 6.38 +#include <GLES2/gl2.h> 6.39 +#define GL_ES 6.40 +#else 6.41 +#include <GL/glew.h> 6.42 +#endif 6.43 + 6.44 +#include "drawtext.h" 6.45 +#include "drawtext_impl.h" 6.46 + 6.47 +struct vertex { 6.48 + float x, y; 6.49 + float s, t; 6.50 +}; 6.51 + 6.52 +struct quad { 6.53 + struct vertex v[6]; 6.54 +}; 6.55 + 6.56 +static void cleanup(void); 6.57 +static void add_glyph(struct glyph *g, float x, float y); 6.58 + 6.59 +#define QBUF_SZ 512 6.60 +static struct quad *qbuf; 6.61 +static int num_quads; 6.62 +static int vattr = -1; 6.63 +static int tattr = -1; 6.64 +static unsigned int font_tex; 6.65 +static int buf_mode = DTX_NBF; 6.66 + 6.67 + 6.68 +int dtx_gl_init(void) 6.69 +{ 6.70 + if(qbuf) { 6.71 + return 0; /* already initialized */ 6.72 + } 6.73 + 6.74 +#ifdef __glew_h__ 6.75 + glewInit(); 6.76 +#endif 6.77 + 6.78 + if(!(qbuf = malloc(QBUF_SZ * sizeof *qbuf))) { 6.79 + return -1; 6.80 + } 6.81 + num_quads = 0; 6.82 + 6.83 + atexit(cleanup); 6.84 + return 0; 6.85 +} 6.86 + 6.87 +static void cleanup(void) 6.88 +{ 6.89 + free(qbuf); 6.90 +} 6.91 + 6.92 + 6.93 +void dtx_vertex_attribs(int vert_attr, int tex_attr) 6.94 +{ 6.95 + vattr = vert_attr; 6.96 + tattr = tex_attr; 6.97 +} 6.98 + 6.99 +static void set_glyphmap_texture(struct dtx_glyphmap *gmap) 6.100 +{ 6.101 + if(!gmap->tex) { 6.102 + glGenTextures(1, &gmap->tex); 6.103 + glBindTexture(GL_TEXTURE_2D, gmap->tex); 6.104 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 6.105 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 6.106 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 6.107 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 6.108 + 6.109 +#ifdef GL_ES 6.110 + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, gmap->xsz, gmap->ysz, 0, GL_ALPHA, GL_UNSIGNED_BYTE, gmap->pixels); 6.111 + glGenerateMipmap(GL_TEXTURE_2D); 6.112 +#else 6.113 + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, gmap->xsz, gmap->ysz, GL_ALPHA, GL_UNSIGNED_BYTE, gmap->pixels); 6.114 +#endif 6.115 + } 6.116 + 6.117 + if(font_tex != gmap->tex) { 6.118 + dtx_flush(); 6.119 + } 6.120 + font_tex = gmap->tex; 6.121 +} 6.122 + 6.123 +void dtx_glyph(int code) 6.124 +{ 6.125 + struct dtx_glyphmap *gmap; 6.126 + 6.127 + if(!dtx_font || !(gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code))) { 6.128 + return; 6.129 + } 6.130 + set_glyphmap_texture(gmap); 6.131 + 6.132 + add_glyph(gmap->glyphs + code - gmap->cstart, 0, 0); 6.133 + dtx_flush(); 6.134 +} 6.135 + 6.136 +static const char *put_char(const char *str, float *pos_x, float *pos_y, int *should_flush) 6.137 +{ 6.138 + struct dtx_glyphmap *gmap; 6.139 + float px, py; 6.140 + int code = dtx_utf8_char_code(str); 6.141 + str = dtx_utf8_next_char((char*)str); 6.142 + 6.143 + if(buf_mode == DTX_LBF && code == '\n') { 6.144 + *should_flush = 1; 6.145 + } 6.146 + 6.147 + px = *pos_x; 6.148 + py = *pos_y; 6.149 + 6.150 + if((gmap = dtx_proc_char(code, pos_x, pos_y))) { 6.151 + int idx = code - gmap->cstart; 6.152 + 6.153 + set_glyphmap_texture(gmap); 6.154 + add_glyph(gmap->glyphs + idx, px, py); 6.155 + } 6.156 + return str; 6.157 +} 6.158 + 6.159 +void dtx_string(const char *str) 6.160 +{ 6.161 + int should_flush = buf_mode == DTX_NBF; 6.162 + float pos_x = 0.0f; 6.163 + float pos_y = 0.0f; 6.164 + 6.165 + if(!dtx_font) { 6.166 + return; 6.167 + } 6.168 + 6.169 + while(*str) { 6.170 + str = put_char(str, &pos_x, &pos_y, &should_flush); 6.171 + } 6.172 + 6.173 + if(should_flush) { 6.174 + dtx_flush(); 6.175 + } 6.176 +} 6.177 + 6.178 +void dtx_printf(const char *fmt, ...) 6.179 +{ 6.180 + va_list ap; 6.181 + int buf_size; 6.182 + char *buf, tmp; 6.183 + 6.184 + if(!dtx_font) { 6.185 + return; 6.186 + } 6.187 + 6.188 + va_start(ap, fmt); 6.189 + buf_size = vsnprintf(&tmp, 0, fmt, ap); 6.190 + va_end(ap); 6.191 + 6.192 + if(buf_size == -1) { 6.193 + buf_size = 512; 6.194 + } 6.195 + 6.196 + buf = alloca(buf_size + 1); 6.197 + va_start(ap, fmt); 6.198 + vsnprintf(buf, buf_size + 1, fmt, ap); 6.199 + va_end(ap); 6.200 + 6.201 + dtx_string(buf); 6.202 +} 6.203 + 6.204 +static void qvertex(struct vertex *v, float x, float y, float s, float t) 6.205 +{ 6.206 + v->x = x; 6.207 + v->y = y; 6.208 + v->s = s; 6.209 + v->t = t; 6.210 +} 6.211 + 6.212 +static void add_glyph(struct glyph *g, float x, float y) 6.213 +{ 6.214 + struct quad *qptr = qbuf + num_quads; 6.215 + 6.216 + x -= g->orig_x; 6.217 + y -= g->orig_y; 6.218 + 6.219 + qvertex(qptr->v + 0, x, y, g->nx, g->ny + g->nheight); 6.220 + qvertex(qptr->v + 1, x + g->width, y, g->nx + g->nwidth, g->ny + g->nheight); 6.221 + qvertex(qptr->v + 2, x + g->width, y + g->height, g->nx + g->nwidth, g->ny); 6.222 + 6.223 + qvertex(qptr->v + 3, x, y, g->nx, g->ny + g->nheight); 6.224 + qvertex(qptr->v + 4, x + g->width, y + g->height, g->nx + g->nwidth, g->ny); 6.225 + qvertex(qptr->v + 5, x, y + g->height, g->nx, g->ny); 6.226 + 6.227 + if(++num_quads >= QBUF_SZ) { 6.228 + dtx_flush(); 6.229 + } 6.230 +} 6.231 + 6.232 +void dtx_flush(void) 6.233 +{ 6.234 + int vbo; 6.235 + 6.236 + if(!num_quads) { 6.237 + return; 6.238 + } 6.239 + 6.240 + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vbo); 6.241 + glBindBuffer(GL_ARRAY_BUFFER, 0); 6.242 + 6.243 +#ifndef GL_ES 6.244 + glPushAttrib(GL_ENABLE_BIT); 6.245 + glEnable(GL_TEXTURE_2D); 6.246 +#endif 6.247 + glBindTexture(GL_TEXTURE_2D, font_tex); 6.248 + 6.249 + if(vattr != -1) { 6.250 + glEnableVertexAttribArray(vattr); 6.251 + glVertexAttribPointer(vattr, 2, GL_FLOAT, 0, sizeof(struct vertex), qbuf); 6.252 +#ifndef GL_ES 6.253 + } else { 6.254 + glEnableClientState(GL_VERTEX_ARRAY); 6.255 + glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), qbuf); 6.256 +#endif 6.257 + } 6.258 + if(tattr != -1) { 6.259 + glEnableVertexAttribArray(tattr); 6.260 + glVertexAttribPointer(tattr, 2, GL_FLOAT, 0, sizeof(struct vertex), &qbuf->v[0].s); 6.261 +#ifndef GL_ES 6.262 + } else { 6.263 + glEnableClientState(GL_TEXTURE_COORD_ARRAY); 6.264 + glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), &qbuf->v[0].s); 6.265 +#endif 6.266 + } 6.267 + 6.268 + glEnable(GL_BLEND); 6.269 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 6.270 + 6.271 + glDepthMask(0); 6.272 + 6.273 + glDrawArrays(GL_TRIANGLES, 0, num_quads * 6); 6.274 + 6.275 + glDepthMask(1); 6.276 + 6.277 + if(vattr != -1) { 6.278 + glDisableVertexAttribArray(vattr); 6.279 +#ifndef GL_ES 6.280 + } else { 6.281 + glDisableClientState(GL_VERTEX_ARRAY); 6.282 +#endif 6.283 + } 6.284 + if(tattr != -1) { 6.285 + glDisableVertexAttribArray(tattr); 6.286 +#ifndef GL_ES 6.287 + } else { 6.288 + glDisableClientState(GL_TEXTURE_COORD_ARRAY); 6.289 +#endif 6.290 + } 6.291 + 6.292 +#ifndef GL_ES 6.293 + glPopAttrib(); 6.294 +#else 6.295 + glDisable(GL_BLEND); 6.296 +#endif 6.297 + 6.298 + if(vbo) { 6.299 + glBindBuffer(GL_ARRAY_BUFFER, vbo); 6.300 + } 6.301 + 6.302 + num_quads = 0; 6.303 +} 6.304 + 6.305 +#endif /* !def NO_OPENGL */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/libs/drawtext/drawtext.h Sun May 31 00:40:26 2015 +0300 7.3 @@ -0,0 +1,188 @@ 7.4 +/* 7.5 +libdrawtext - a simple library for fast text rendering in OpenGL 7.6 +Copyright (C) 2011-2014 John Tsiombikas <nuclear@member.fsf.org> 7.7 + 7.8 +This program is free software: you can redistribute it and/or modify 7.9 +it under the terms of the GNU Lesser General Public License as published by 7.10 +the Free Software Foundation, either version 3 of the License, or 7.11 +(at your option) any later version. 7.12 + 7.13 +This program is distributed in the hope that it will be useful, 7.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 7.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.16 +GNU Lesser General Public License for more details. 7.17 + 7.18 +You should have received a copy of the GNU Lesser General Public License 7.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 7.20 +*/ 7.21 +#ifndef LIBDRAWTEXT_H_ 7.22 +#define LIBDRAWTEXT_H_ 7.23 + 7.24 +#include <stdio.h> 7.25 +#include <stdlib.h> 7.26 + 7.27 +struct dtx_font; 7.28 +struct dtx_glyphmap; 7.29 + 7.30 +/* draw buffering modes */ 7.31 +enum { 7.32 + DTX_NBF, /* unbuffered */ 7.33 + DTX_LBF, /* line buffered */ 7.34 + DTX_FBF /* fully buffered */ 7.35 +}; 7.36 + 7.37 +struct dtx_box { 7.38 + float x, y; 7.39 + float width, height; 7.40 +}; 7.41 + 7.42 +#ifdef __cplusplus 7.43 +extern "C" { 7.44 +#endif 7.45 + 7.46 +/* Open a truetype/opentype/whatever font. 7.47 + * 7.48 + * If sz is non-zero, the default ASCII glyphmap at the requested point size is 7.49 + * automatically created as well, and ready to use. 7.50 + * 7.51 + * To use other unicode ranges and different font sizes you must first call 7.52 + * dtx_prepare or dtx_prepare_range before issuing any drawing calls, otherwise 7.53 + * nothing will be rendered. 7.54 + */ 7.55 +struct dtx_font *dtx_open_font(const char *fname, int sz); 7.56 +/* open a font by loading a precompiled glyphmap (see: dtx_save_glyphmap) 7.57 + * this works even when compiled without freetype support 7.58 + */ 7.59 +struct dtx_font *dtx_open_font_glyphmap(const char *fname); 7.60 +/* close a font opened by either of the above */ 7.61 +void dtx_close_font(struct dtx_font *fnt); 7.62 + 7.63 +/* prepare an ASCII glyphmap for the specified font size */ 7.64 +void dtx_prepare(struct dtx_font *fnt, int sz); 7.65 +/* prepare an arbitrary unicode range glyphmap for the specified font size */ 7.66 +void dtx_prepare_range(struct dtx_font *fnt, int sz, int cstart, int cend); 7.67 + 7.68 +/* Finds the glyphmap that contains the specified character code and matches the requested size 7.69 + * Returns null if it hasn't been created (you should call dtx_prepare/dtx_prepare_range). 7.70 + */ 7.71 +struct dtx_glyphmap *dtx_get_font_glyphmap(struct dtx_font *fnt, int sz, int code); 7.72 + 7.73 +/* Finds the glyphmap that contains the specified unicode range and matches the requested font size 7.74 + * Will automatically generate one if it can't find it. 7.75 + */ 7.76 +struct dtx_glyphmap *dtx_get_font_glyphmap_range(struct dtx_font *fnt, int sz, int cstart, int cend); 7.77 + 7.78 +/* Creates and returns a glyphmap for a particular unicode range and font size. 7.79 + * The generated glyphmap is added to the font's list of glyphmaps. 7.80 + */ 7.81 +struct dtx_glyphmap *dtx_create_glyphmap_range(struct dtx_font *fnt, int sz, int cstart, int cend); 7.82 +/* free a glyphmap */ 7.83 +void dtx_free_glyphmap(struct dtx_glyphmap *gmap); 7.84 + 7.85 +/* returns a pointer to the raster image of a glyphmap (1 byte per pixel grayscale) */ 7.86 +unsigned char *dtx_get_glyphmap_image(struct dtx_glyphmap *gmap); 7.87 +/* returns the width of the glyphmap image in pixels */ 7.88 +int dtx_get_glyphmap_width(struct dtx_glyphmap *gmap); 7.89 +/* returns the height of the glyphmap image in pixels */ 7.90 +int dtx_get_glyphmap_height(struct dtx_glyphmap *gmap); 7.91 + 7.92 +/* The following functions can be used even when the library is compiled without 7.93 + * freetype support. 7.94 + */ 7.95 +struct dtx_glyphmap *dtx_load_glyphmap(const char *fname); 7.96 +struct dtx_glyphmap *dtx_load_glyphmap_stream(FILE *fp); 7.97 +int dtx_save_glyphmap(const char *fname, const struct dtx_glyphmap *gmap); 7.98 +int dtx_save_glyphmap_stream(FILE *fp, const struct dtx_glyphmap *gmap); 7.99 + 7.100 +/* adds a glyphmap to a font */ 7.101 +void dtx_add_glyphmap(struct dtx_font *fnt, struct dtx_glyphmap *gmap); 7.102 + 7.103 +/* ---- rendering ---- */ 7.104 + 7.105 +/* before drawing anything this function must set the font to use */ 7.106 +void dtx_use_font(struct dtx_font *fnt, int sz); 7.107 + 7.108 +/* sets the buffering mode 7.109 + * - DTX_NBUF: every call to dtx_string gets rendered immediately. 7.110 + * - DTX_LBUF: renders when the buffer is full or the string contains a newline. 7.111 + * - DTX_FBUF: renders only when the buffer is full (you must call dtx_flush explicitly). 7.112 + */ 7.113 +void dtx_draw_buffering(int mode); 7.114 + 7.115 +/* Sets the vertex attribute indices to use for passing vertex and texture coordinate 7.116 + * data. By default both are -1 which means you don't have to use a shader, and if you 7.117 + * do they are accessible through gl_Vertex and gl_MultiTexCoord0, as usual. 7.118 + * 7.119 + * NOTE: If you are using OpenGL ES 2.x or OpenGL >= 3.1 pure (non-compatibility) context 7.120 + * you must specify valid attribute indices. 7.121 + */ 7.122 +void dtx_vertex_attribs(int vert_attr, int tex_attr); 7.123 + 7.124 +/* draws a single glyph at the origin */ 7.125 +void dtx_glyph(int code); 7.126 +/* draws a utf-8 string starting at the origin. \n \r and \t are handled appropriately. */ 7.127 +void dtx_string(const char *str); 7.128 + 7.129 +void dtx_printf(const char *fmt, ...); 7.130 + 7.131 +/* render any pending glyphs (see dtx_draw_buffering) */ 7.132 +void dtx_flush(void); 7.133 + 7.134 + 7.135 +/* ---- encodings ---- */ 7.136 + 7.137 +/* returns a pointer to the next character in a utf-8 stream */ 7.138 +char *dtx_utf8_next_char(char *str); 7.139 + 7.140 +/* returns the unicode character codepoint of the utf-8 character starting at str */ 7.141 +int dtx_utf8_char_code(const char *str); 7.142 + 7.143 +/* returns the number of bytes of the utf-8 character starting at str */ 7.144 +int dtx_utf8_nbytes(const char *str); 7.145 + 7.146 +/* returns the number of utf-8 character in a zero-terminated utf-8 string */ 7.147 +int dtx_utf8_char_count(const char *str); 7.148 + 7.149 +/* Converts a unicode code-point to a utf-8 character by filling in the buffer 7.150 + * passed at the second argument, and returns the number of bytes taken by that 7.151 + * utf-8 character. 7.152 + * It's valid to pass a null buffer pointer, in which case only the byte count is 7.153 + * returned (useful to figure out how much memory to allocate for a buffer). 7.154 + */ 7.155 +size_t dtx_utf8_from_char_code(int code, char *buf); 7.156 + 7.157 +/* Converts a unicode utf-16 wchar_t string to utf-8, filling in the buffer passed 7.158 + * at the second argument. Returns the size of the resulting string in bytes. 7.159 + * 7.160 + * It's valid to pass a null buffer pointer, in which case only the size gets 7.161 + * calculated and returned, which is useful for figuring out how much memory to 7.162 + * allocate for the utf-8 buffer. 7.163 + */ 7.164 +size_t dtx_utf8_from_string(const wchar_t *str, char *buf); 7.165 + 7.166 + 7.167 +/* ---- metrics ---- */ 7.168 +float dtx_line_height(void); 7.169 + 7.170 +/* rendered dimensions of a single glyph */ 7.171 +void dtx_glyph_box(int code, struct dtx_box *box); 7.172 +float dtx_glyph_width(int code); 7.173 +float dtx_glyph_height(int code); 7.174 + 7.175 +/* rendered dimensions of a string */ 7.176 +void dtx_string_box(const char *str, struct dtx_box *box); 7.177 +float dtx_string_width(const char *str); 7.178 +float dtx_string_height(const char *str); 7.179 + 7.180 +/* returns the horizontal position of the n-th character of the rendered string 7.181 + * (useful for placing cursors) 7.182 + */ 7.183 +float dtx_char_pos(const char *str, int n); 7.184 + 7.185 +int dtx_char_at_pt(const char *str, float pt); 7.186 + 7.187 +#ifdef __cplusplus 7.188 +} 7.189 +#endif 7.190 + 7.191 +#endif /* LIBDRAWTEXT_H_ */
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/libs/drawtext/drawtext_impl.h Sun May 31 00:40:26 2015 +0300 8.3 @@ -0,0 +1,72 @@ 8.4 +/* 8.5 +libdrawtext - a simple library for fast text rendering in OpenGL 8.6 +Copyright (C) 2011-2012 John Tsiombikas <nuclear@member.fsf.org> 8.7 + 8.8 +This program is free software: you can redistribute it and/or modify 8.9 +it under the terms of the GNU Lesser General Public License as published by 8.10 +the Free Software Foundation, either version 3 of the License, or 8.11 +(at your option) any later version. 8.12 + 8.13 +This program is distributed in the hope that it will be useful, 8.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 8.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.16 +GNU Lesser General Public License for more details. 8.17 + 8.18 +You should have received a copy of the GNU Lesser General Public License 8.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 8.20 +*/ 8.21 +#ifndef TEXT_IMPL_H_ 8.22 +#define TEXT_IMPL_H_ 8.23 + 8.24 +struct glyph { 8.25 + int code; 8.26 + float x, y, width, height; 8.27 + /* normalized coords [0, 1] */ 8.28 + float nx, ny, nwidth, nheight; 8.29 + float orig_x, orig_y; 8.30 + float advance; 8.31 + struct glyph *next; 8.32 +}; 8.33 + 8.34 +struct dtx_glyphmap { 8.35 + int ptsize; 8.36 + 8.37 + int xsz, ysz; 8.38 + unsigned char *pixels; 8.39 + unsigned int tex; 8.40 + 8.41 + int cstart, cend; /* character range */ 8.42 + int crange; 8.43 + 8.44 + float line_advance; 8.45 + 8.46 + struct glyph *glyphs; 8.47 + struct dtx_glyphmap *next; 8.48 +}; 8.49 + 8.50 +struct dtx_font { 8.51 + /* freetype FT_Face */ 8.52 + void *face; 8.53 + 8.54 + /* list of glyphmaps */ 8.55 + struct dtx_glyphmap *gmaps; 8.56 + 8.57 + /* last returned glyphmap (cache) */ 8.58 + struct dtx_glyphmap *last_gmap; 8.59 +}; 8.60 + 8.61 + 8.62 +struct dtx_font *dtx_font; 8.63 +int dtx_font_sz; 8.64 + 8.65 + 8.66 +#define fperror(str) \ 8.67 + fprintf(stderr, "%s: %s: %s\n", __FUNCTION__, (str), strerror(errno)) 8.68 + 8.69 +int dtx_gl_init(void); 8.70 + 8.71 +/* returns zero if it should NOT be printed and modifies xpos/ypos */ 8.72 +/* implemented in font.c */ 8.73 +struct dtx_glyphmap *dtx_proc_char(int code, float *xpos, float *ypos); 8.74 + 8.75 +#endif /* TEXT_IMPL_H_ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/libs/drawtext/font.c Sun May 31 00:40:26 2015 +0300 9.3 @@ -0,0 +1,773 @@ 9.4 +/* 9.5 +libdrawtext - a simple library for fast text rendering in OpenGL 9.6 +Copyright (C) 2011-2014 John Tsiombikas <nuclear@member.fsf.org> 9.7 + 9.8 +This program is free software: you can redistribute it and/or modify 9.9 +it under the terms of the GNU Lesser General Public License as published by 9.10 +the Free Software Foundation, either version 3 of the License, or 9.11 +(at your option) any later version. 9.12 + 9.13 +This program is distributed in the hope that it will be useful, 9.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 9.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9.16 +GNU Lesser General Public License for more details. 9.17 + 9.18 +You should have received a copy of the GNU Lesser General Public License 9.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 9.20 +*/ 9.21 +#ifndef NO_FREETYPE 9.22 +#define USE_FREETYPE 9.23 +#endif 9.24 + 9.25 +#include <stdio.h> 9.26 +#include <stdlib.h> 9.27 +#include <string.h> 9.28 +#include <math.h> 9.29 +#include <limits.h> 9.30 +#include <ctype.h> 9.31 +#include <float.h> 9.32 +#include <errno.h> 9.33 +#ifdef USE_FREETYPE 9.34 +#include <ft2build.h> 9.35 +#include FT_FREETYPE_H 9.36 +#endif 9.37 +#include "drawtext.h" 9.38 +#include "drawtext_impl.h" 9.39 + 9.40 +#define FTSZ_TO_PIXELS(x) ((x) / 64) 9.41 +#define MAX_IMG_WIDTH 4096 9.42 + 9.43 + 9.44 +#ifdef USE_FREETYPE 9.45 +static int init_freetype(void); 9.46 +static void cleanup(void); 9.47 + 9.48 +static void calc_best_size(int total_width, int max_gwidth, int max_gheight, 9.49 + int padding, int pow2, int *imgw, int *imgh); 9.50 +static int next_pow2(int x); 9.51 + 9.52 +static FT_Library ft; 9.53 + 9.54 + 9.55 +static int init_done; 9.56 + 9.57 +static int init_freetype(void) 9.58 +{ 9.59 + if(!init_done) { 9.60 + if(FT_Init_FreeType(&ft) != 0) { 9.61 + return -1; 9.62 + } 9.63 + atexit(cleanup); 9.64 + init_done = 1; 9.65 + } 9.66 + return 0; 9.67 +} 9.68 + 9.69 +static void cleanup(void) 9.70 +{ 9.71 + if(init_done) { 9.72 + FT_Done_FreeType(ft); 9.73 + } 9.74 +} 9.75 +#endif /* USE_FREETYPE */ 9.76 + 9.77 +struct dtx_font *dtx_open_font(const char *fname, int sz) 9.78 +{ 9.79 + struct dtx_font *fnt = 0; 9.80 + 9.81 +#ifdef USE_FREETYPE 9.82 + init_freetype(); 9.83 + 9.84 + if(!(fnt = calloc(1, sizeof *fnt))) { 9.85 + fperror("failed to allocate font structure"); 9.86 + return 0; 9.87 + } 9.88 + 9.89 + if(FT_New_Face(ft, fname, 0, (FT_Face*)&fnt->face) != 0) { 9.90 + fprintf(stderr, "failed to open font file: %s\n", fname); 9.91 + return 0; 9.92 + } 9.93 + 9.94 + /* pre-create the extended ASCII range glyphmap */ 9.95 + if(sz) { 9.96 + dtx_prepare_range(fnt, sz, 0, 256); 9.97 + 9.98 + if(!dtx_font) { 9.99 + dtx_use_font(fnt, sz); 9.100 + } 9.101 + } 9.102 +#else 9.103 + fprintf(stderr, "ignoring call to dtx_open_font: not compiled with freetype support!\n"); 9.104 +#endif 9.105 + 9.106 + return fnt; 9.107 +} 9.108 + 9.109 +struct dtx_font *dtx_open_font_glyphmap(const char *fname) 9.110 +{ 9.111 + struct dtx_font *fnt; 9.112 + struct dtx_glyphmap *gmap; 9.113 + 9.114 + if(!(fnt = calloc(1, sizeof *fnt))) { 9.115 + fperror("failed to allocate font structure"); 9.116 + return 0; 9.117 + } 9.118 + 9.119 + if(fname) { 9.120 + if(!(gmap = dtx_load_glyphmap(fname))) { 9.121 + free(fnt); 9.122 + return 0; 9.123 + } 9.124 + 9.125 + dtx_add_glyphmap(fnt, gmap); 9.126 + 9.127 + if(!dtx_font) { 9.128 + dtx_use_font(fnt, gmap->ptsize); 9.129 + } 9.130 + } 9.131 + return fnt; 9.132 +} 9.133 + 9.134 +void dtx_close_font(struct dtx_font *fnt) 9.135 +{ 9.136 + if(!fnt) return; 9.137 + 9.138 +#ifdef USE_FREETYPE 9.139 + FT_Done_Face(fnt->face); 9.140 +#endif 9.141 + 9.142 + /* destroy the glyphmaps */ 9.143 + while(fnt->gmaps) { 9.144 + void *tmp = fnt->gmaps; 9.145 + fnt->gmaps = fnt->gmaps->next; 9.146 + dtx_free_glyphmap(tmp); 9.147 + } 9.148 + 9.149 + free(fnt); 9.150 +} 9.151 + 9.152 +void dtx_prepare(struct dtx_font *fnt, int sz) 9.153 +{ 9.154 + if(!dtx_get_font_glyphmap_range(fnt, sz, 0, 256)) { 9.155 + fprintf(stderr, "%s: failed (sz: %d, range: 0-255 [ascii])\n", __FUNCTION__, sz); 9.156 + } 9.157 +} 9.158 + 9.159 +void dtx_prepare_range(struct dtx_font *fnt, int sz, int cstart, int cend) 9.160 +{ 9.161 + if(!dtx_get_font_glyphmap_range(fnt, sz, cstart, cend)) { 9.162 + fprintf(stderr, "%s: failed (sz: %d, range: %d-%d)\n", __FUNCTION__, sz, cstart, cend); 9.163 + } 9.164 +} 9.165 + 9.166 +struct dtx_glyphmap *dtx_get_font_glyphmap(struct dtx_font *fnt, int sz, int code) 9.167 +{ 9.168 + struct dtx_glyphmap *gm; 9.169 + 9.170 + /* check to see if the last we've given out fits the bill */ 9.171 + if(fnt->last_gmap && code >= fnt->last_gmap->cstart && code < fnt->last_gmap->cend && fnt->last_gmap->ptsize == sz) { 9.172 + return fnt->last_gmap; 9.173 + } 9.174 + 9.175 + /* otherwise search for the appropriate glyphmap */ 9.176 + gm = fnt->gmaps; 9.177 + while(gm) { 9.178 + if(code >= gm->cstart && code < gm->cend && sz == gm->ptsize) { 9.179 + fnt->last_gmap = gm; 9.180 + return gm; 9.181 + } 9.182 + gm = gm->next; 9.183 + } 9.184 + return 0; 9.185 +} 9.186 + 9.187 +struct dtx_glyphmap *dtx_get_font_glyphmap_range(struct dtx_font *fnt, int sz, int cstart, int cend) 9.188 +{ 9.189 + struct dtx_glyphmap *gm; 9.190 + 9.191 + /* search the available glyphmaps to see if we've got one that includes 9.192 + * the requested range 9.193 + */ 9.194 + gm = fnt->gmaps; 9.195 + while(gm) { 9.196 + if(gm->cstart <= cstart && gm->cend >= cend && gm->ptsize == sz) { 9.197 + return gm; 9.198 + } 9.199 + gm = gm->next; 9.200 + } 9.201 + 9.202 + /* not found, create one and add it to the list */ 9.203 + if(!(gm = dtx_create_glyphmap_range(fnt, sz, cstart, cend))) { 9.204 + return 0; 9.205 + } 9.206 + return gm; 9.207 +} 9.208 + 9.209 +struct dtx_glyphmap *dtx_create_glyphmap_range(struct dtx_font *fnt, int sz, int cstart, int cend) 9.210 +{ 9.211 + struct dtx_glyphmap *gmap = 0; 9.212 + 9.213 +#ifdef USE_FREETYPE 9.214 + FT_Face face = fnt->face; 9.215 + int i, j; 9.216 + int gx, gy; 9.217 + int padding = 4; 9.218 + int total_width, max_width, max_height; 9.219 + 9.220 + FT_Set_Char_Size(fnt->face, 0, sz * 64, 72, 72); 9.221 + 9.222 + if(!(gmap = calloc(1, sizeof *gmap))) { 9.223 + return 0; 9.224 + } 9.225 + 9.226 + gmap->ptsize = sz; 9.227 + gmap->cstart = cstart; 9.228 + gmap->cend = cend; 9.229 + gmap->crange = cend - cstart; 9.230 + gmap->line_advance = FTSZ_TO_PIXELS((float)face->size->metrics.height); 9.231 + 9.232 + if(!(gmap->glyphs = malloc(gmap->crange * sizeof *gmap->glyphs))) { 9.233 + free(gmap); 9.234 + return 0; 9.235 + } 9.236 + 9.237 + total_width = padding; 9.238 + max_width = max_height = 0; 9.239 + 9.240 + for(i=0; i<gmap->crange; i++) { 9.241 + int w, h; 9.242 + 9.243 + FT_Load_Char(face, i + cstart, 0); 9.244 + w = FTSZ_TO_PIXELS(face->glyph->metrics.width); 9.245 + h = FTSZ_TO_PIXELS(face->glyph->metrics.height); 9.246 + 9.247 + if(w > max_width) max_width = w; 9.248 + if(h > max_height) max_height = h; 9.249 + 9.250 + total_width += w + padding; 9.251 + } 9.252 + 9.253 + calc_best_size(total_width, max_width, max_height, padding, 1, &gmap->xsz, &gmap->ysz); 9.254 + 9.255 + if(!(gmap->pixels = malloc(gmap->xsz * gmap->ysz))) { 9.256 + free(gmap->glyphs); 9.257 + free(gmap); 9.258 + return 0; 9.259 + } 9.260 + memset(gmap->pixels, 0, gmap->xsz * gmap->ysz); 9.261 + 9.262 + gx = padding; 9.263 + gy = padding; 9.264 + 9.265 + for(i=0; i<gmap->crange; i++) { 9.266 + float gwidth, gheight; 9.267 + unsigned char *src, *dst; 9.268 + FT_GlyphSlot glyph; 9.269 + 9.270 + FT_Load_Char(face, i + cstart, FT_LOAD_RENDER); 9.271 + glyph = face->glyph; 9.272 + gwidth = FTSZ_TO_PIXELS((float)glyph->metrics.width); 9.273 + gheight = FTSZ_TO_PIXELS((float)glyph->metrics.height); 9.274 + 9.275 + if(gx > gmap->xsz - gwidth - padding) { 9.276 + gx = padding; 9.277 + gy += max_height + padding; 9.278 + } 9.279 + 9.280 + src = glyph->bitmap.buffer; 9.281 + dst = gmap->pixels + gy * gmap->xsz + gx; 9.282 + 9.283 + for(j=0; j<glyph->bitmap.rows; j++) { 9.284 + memcpy(dst, src, glyph->bitmap.width); 9.285 + dst += gmap->xsz; 9.286 + src += glyph->bitmap.pitch; 9.287 + } 9.288 + 9.289 + gmap->glyphs[i].code = i; 9.290 + gmap->glyphs[i].x = gx - 1; 9.291 + gmap->glyphs[i].y = gy - 1; 9.292 + gmap->glyphs[i].width = gwidth + 2; 9.293 + gmap->glyphs[i].height = gheight + 2; 9.294 + gmap->glyphs[i].orig_x = -FTSZ_TO_PIXELS((float)glyph->metrics.horiBearingX) + 1; 9.295 + gmap->glyphs[i].orig_y = FTSZ_TO_PIXELS((float)glyph->metrics.height - glyph->metrics.horiBearingY) + 1; 9.296 + gmap->glyphs[i].advance = FTSZ_TO_PIXELS((float)glyph->metrics.horiAdvance); 9.297 + /* also precalc normalized */ 9.298 + gmap->glyphs[i].nx = (float)gmap->glyphs[i].x / (float)gmap->xsz; 9.299 + gmap->glyphs[i].ny = (float)gmap->glyphs[i].y / (float)gmap->ysz; 9.300 + gmap->glyphs[i].nwidth = (float)gmap->glyphs[i].width / (float)gmap->xsz; 9.301 + gmap->glyphs[i].nheight = (float)gmap->glyphs[i].height / (float)gmap->ysz; 9.302 + 9.303 + gx += gwidth + padding; 9.304 + } 9.305 + 9.306 + /* add it to the glyphmaps list of the font */ 9.307 + dtx_add_glyphmap(fnt, gmap); 9.308 +#endif /* USE_FREETYPE */ 9.309 + 9.310 + return gmap; 9.311 +} 9.312 + 9.313 +void dtx_free_glyphmap(struct dtx_glyphmap *gmap) 9.314 +{ 9.315 + if(gmap) { 9.316 + free(gmap->pixels); 9.317 + free(gmap->glyphs); 9.318 + free(gmap); 9.319 + } 9.320 +} 9.321 + 9.322 +unsigned char *dtx_get_glyphmap_pixels(struct dtx_glyphmap *gmap) 9.323 +{ 9.324 + return gmap->pixels; 9.325 +} 9.326 + 9.327 +int dtx_get_glyphmap_width(struct dtx_glyphmap *gmap) 9.328 +{ 9.329 + return gmap->xsz; 9.330 +} 9.331 + 9.332 +int dtx_get_glyphmap_height(struct dtx_glyphmap *gmap) 9.333 +{ 9.334 + return gmap->ysz; 9.335 +} 9.336 + 9.337 +struct dtx_glyphmap *dtx_load_glyphmap(const char *fname) 9.338 +{ 9.339 + FILE *fp; 9.340 + struct dtx_glyphmap *gmap; 9.341 + 9.342 + if(!(fp = fopen(fname, "rb"))) { 9.343 + return 0; 9.344 + } 9.345 + gmap = dtx_load_glyphmap_stream(fp); 9.346 + fclose(fp); 9.347 + return gmap; 9.348 +} 9.349 + 9.350 +struct dtx_glyphmap *dtx_load_glyphmap_stream(FILE *fp) 9.351 +{ 9.352 + char buf[512]; 9.353 + int hdr_lines = 0; 9.354 + struct dtx_glyphmap *gmap; 9.355 + struct glyph *glyphs = 0; 9.356 + struct glyph *g; 9.357 + int min_code = INT_MAX; 9.358 + int max_code = INT_MIN; 9.359 + int i, max_pixval, num_pixels; 9.360 + 9.361 + if(!(gmap = calloc(1, sizeof *gmap))) { 9.362 + fperror("failed to allocate glyphmap"); 9.363 + return 0; 9.364 + } 9.365 + gmap->ptsize = -1; 9.366 + gmap->line_advance = FLT_MIN; 9.367 + 9.368 + while(hdr_lines < 3) { 9.369 + char *line = buf; 9.370 + if(!fgets(buf, sizeof buf, fp)) { 9.371 + fperror("unexpected end of file"); 9.372 + goto err; 9.373 + } 9.374 + 9.375 + while(isspace(*line)) { 9.376 + line++; 9.377 + } 9.378 + 9.379 + if(line[0] == '#') { 9.380 + int c, res; 9.381 + float x, y, xsz, ysz, orig_x, orig_y, adv, line_adv; 9.382 + int ptsize; 9.383 + 9.384 + if((res = sscanf(line + 1, " size: %d\n", &ptsize)) == 1) { 9.385 + gmap->ptsize = ptsize; 9.386 + 9.387 + } else if((res = sscanf(line + 1, " advance: %f\n", &line_adv)) == 1) { 9.388 + gmap->line_advance = line_adv; 9.389 + 9.390 + } else if((res = sscanf(line + 1, " %d: %fx%f+%f+%f o:%f,%f adv:%f\n", 9.391 + &c, &xsz, &ysz, &x, &y, &orig_x, &orig_y, &adv)) == 8) { 9.392 + if(!(g = malloc(sizeof *g))) { 9.393 + fperror("failed to allocate glyph"); 9.394 + goto err; 9.395 + } 9.396 + g->code = c; 9.397 + g->x = x; 9.398 + g->y = y; 9.399 + g->width = xsz; 9.400 + g->height = ysz; 9.401 + g->orig_x = orig_x; 9.402 + g->orig_y = orig_y; 9.403 + g->advance = adv; 9.404 + /* normalized coordinates will be precalculated after everything is loaded */ 9.405 + 9.406 + g->next = glyphs; 9.407 + glyphs = g; 9.408 + 9.409 + if(c < min_code) { 9.410 + min_code = c; 9.411 + } 9.412 + if(c > max_code) { 9.413 + max_code = c; 9.414 + } 9.415 + 9.416 + } else { 9.417 + fprintf(stderr, "%s: invalid glyph info line\n", __FUNCTION__); 9.418 + goto err; 9.419 + } 9.420 + 9.421 + } else { 9.422 + switch(hdr_lines) { 9.423 + case 0: 9.424 + if(0[line] != 'P' || 1[line] != '6') { 9.425 + fprintf(stderr, "%s: invalid file format (magic)\n", __FUNCTION__); 9.426 + goto err; 9.427 + } 9.428 + break; 9.429 + 9.430 + case 1: 9.431 + if(sscanf(line, "%d %d", &gmap->xsz, &gmap->ysz) != 2) { 9.432 + fprintf(stderr, "%s: invalid file format (dim)\n", __FUNCTION__); 9.433 + goto err; 9.434 + } 9.435 + break; 9.436 + 9.437 + case 2: 9.438 + { 9.439 + char *endp; 9.440 + max_pixval = strtol(line, &endp, 10); 9.441 + if(endp == line) { 9.442 + fprintf(stderr, "%s: invalid file format (maxval)\n", __FUNCTION__); 9.443 + goto err; 9.444 + } 9.445 + } 9.446 + break; 9.447 + 9.448 + default: 9.449 + break; /* can't happen */ 9.450 + } 9.451 + hdr_lines++; 9.452 + } 9.453 + } 9.454 + 9.455 + if(gmap->ptsize == -1 || gmap->line_advance == FLT_MIN) { 9.456 + fprintf(stderr, "%s: invalid glyphmap, insufficient information in ppm comments\n", __FUNCTION__); 9.457 + goto err; 9.458 + } 9.459 + 9.460 + /* precalculate normalized glyph coordinates */ 9.461 + g = glyphs; 9.462 + while(g) { 9.463 + g->nx = g->x / gmap->xsz; 9.464 + g->ny = g->y / gmap->ysz; 9.465 + g->nwidth = g->width / gmap->xsz; 9.466 + g->nheight = g->height / gmap->ysz; 9.467 + g = g->next; 9.468 + } 9.469 + 9.470 + num_pixels = gmap->xsz * gmap->ysz; 9.471 + if(!(gmap->pixels = malloc(num_pixels))) { 9.472 + fperror("failed to allocate pixels"); 9.473 + goto err; 9.474 + } 9.475 + 9.476 + for(i=0; i<num_pixels; i++) { 9.477 + long c = fgetc(fp); 9.478 + if(c == -1) { 9.479 + fprintf(stderr, "unexpected end of file while reading pixels\n"); 9.480 + goto err; 9.481 + } 9.482 + gmap->pixels[i] = 255 * c / max_pixval; 9.483 + fseek(fp, 2, SEEK_CUR); 9.484 + } 9.485 + 9.486 + gmap->cstart = min_code; 9.487 + gmap->cend = max_code + 1; 9.488 + gmap->crange = gmap->cend - gmap->cstart; 9.489 + 9.490 + if(!(gmap->glyphs = calloc(gmap->crange, sizeof *gmap->glyphs))) { 9.491 + fperror("failed to allocate glyph info"); 9.492 + goto err; 9.493 + } 9.494 + 9.495 + while(glyphs) { 9.496 + struct glyph *g = glyphs; 9.497 + glyphs = glyphs->next; 9.498 + 9.499 + gmap->glyphs[g->code - gmap->cstart] = *g; 9.500 + free(g); 9.501 + } 9.502 + return gmap; 9.503 + 9.504 +err: 9.505 + dtx_free_glyphmap(gmap); 9.506 + while(glyphs) { 9.507 + void *tmp = glyphs; 9.508 + glyphs = glyphs->next; 9.509 + free(tmp); 9.510 + } 9.511 + return 0; 9.512 +} 9.513 + 9.514 +int dtx_save_glyphmap(const char *fname, const struct dtx_glyphmap *gmap) 9.515 +{ 9.516 + FILE *fp; 9.517 + int res; 9.518 + 9.519 + if(!(fp = fopen(fname, "wb"))) { 9.520 + fprintf(stderr, "%s: failed to open file: %s: %s\n", __FUNCTION__, fname, strerror(errno)); 9.521 + return -1; 9.522 + } 9.523 + res = dtx_save_glyphmap_stream(fp, gmap); 9.524 + fclose(fp); 9.525 + return res; 9.526 +} 9.527 + 9.528 +int dtx_save_glyphmap_stream(FILE *fp, const struct dtx_glyphmap *gmap) 9.529 +{ 9.530 + int i, num_pixels; 9.531 + struct glyph *g = gmap->glyphs; 9.532 + 9.533 + fprintf(fp, "P6\n%d %d\n", gmap->xsz, gmap->ysz); 9.534 + fprintf(fp, "# size: %d\n", gmap->ptsize); 9.535 + fprintf(fp, "# advance: %g\n", gmap->line_advance); 9.536 + for(i=0; i<gmap->crange; i++) { 9.537 + fprintf(fp, "# %d: %gx%g+%g+%g o:%g,%g adv:%g\n", g->code, g->width, g->height, g->x, g->y, 9.538 + g->orig_x, g->orig_y, g->advance); 9.539 + g++; 9.540 + } 9.541 + fprintf(fp, "255\n"); 9.542 + 9.543 + num_pixels = gmap->xsz * gmap->ysz; 9.544 + for(i=0; i<num_pixels; i++) { 9.545 + int c = gmap->pixels[i]; 9.546 + fputc(c, fp); 9.547 + fputc(c, fp); 9.548 + fputc(c, fp); 9.549 + } 9.550 + return 0; 9.551 +} 9.552 + 9.553 +void dtx_add_glyphmap(struct dtx_font *fnt, struct dtx_glyphmap *gmap) 9.554 +{ 9.555 + gmap->next = fnt->gmaps; 9.556 + fnt->gmaps = gmap; 9.557 +} 9.558 + 9.559 + 9.560 +void dtx_use_font(struct dtx_font *fnt, int sz) 9.561 +{ 9.562 + dtx_gl_init(); 9.563 + 9.564 + dtx_font = fnt; 9.565 + dtx_font_sz = sz; 9.566 +} 9.567 + 9.568 +float dtx_line_height(void) 9.569 +{ 9.570 + struct dtx_glyphmap *gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, '\n'); 9.571 + 9.572 + return gmap->line_advance; 9.573 +} 9.574 + 9.575 +void dtx_glyph_box(int code, struct dtx_box *box) 9.576 +{ 9.577 + int cidx; 9.578 + struct dtx_glyphmap *gmap; 9.579 + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); 9.580 + 9.581 + cidx = code - gmap->cstart; 9.582 + 9.583 + box->x = gmap->glyphs[cidx].orig_x; 9.584 + box->y = gmap->glyphs[cidx].orig_y; 9.585 + box->width = gmap->glyphs[cidx].width; 9.586 + box->height = gmap->glyphs[cidx].height; 9.587 +} 9.588 + 9.589 +float dtx_glyph_width(int code) 9.590 +{ 9.591 + struct dtx_box box; 9.592 + dtx_glyph_box(code, &box); 9.593 + return box.width; 9.594 +} 9.595 + 9.596 +float dtx_glyph_height(int code) 9.597 +{ 9.598 + struct dtx_box box; 9.599 + dtx_glyph_box(code, &box); 9.600 + return box.height; 9.601 +} 9.602 + 9.603 +void dtx_string_box(const char *str, struct dtx_box *box) 9.604 +{ 9.605 + int code; 9.606 + float pos_x = 0.0f, pos_y = 0.0f; 9.607 + struct glyph *g = 0; 9.608 + float x0, y0, x1, y1; 9.609 + 9.610 + x0 = y0 = FLT_MAX; 9.611 + x1 = y1 = -FLT_MAX; 9.612 + 9.613 + while(*str) { 9.614 + float px, py; 9.615 + struct dtx_glyphmap *gmap; 9.616 + 9.617 + code = dtx_utf8_char_code(str); 9.618 + str = dtx_utf8_next_char((char*)str); 9.619 + 9.620 + px = pos_x; 9.621 + py = pos_y; 9.622 + 9.623 + if((gmap = dtx_proc_char(code, &pos_x, &pos_y))) { 9.624 + g = gmap->glyphs + code - gmap->cstart; 9.625 + 9.626 + if(px + g->orig_x < x0) { 9.627 + x0 = px + g->orig_x; 9.628 + } 9.629 + if(py - g->orig_y < y0) { 9.630 + y0 = py - g->orig_y; 9.631 + } 9.632 + if(px + g->orig_x + g->width > x1) { 9.633 + x1 = px + g->orig_x + g->width; 9.634 + } 9.635 + if(py - g->orig_y + g->height > y1) { 9.636 + y1 = py - g->orig_y + g->height; 9.637 + } 9.638 + } 9.639 + } 9.640 + 9.641 + box->x = x0; 9.642 + box->y = y0; 9.643 + box->width = x1 - x0; 9.644 + box->height = y1 - y0; 9.645 +} 9.646 + 9.647 +float dtx_string_width(const char *str) 9.648 +{ 9.649 + struct dtx_box box; 9.650 + 9.651 + dtx_string_box(str, &box); 9.652 + return box.width; 9.653 +} 9.654 + 9.655 +float dtx_string_height(const char *str) 9.656 +{ 9.657 + struct dtx_box box; 9.658 + 9.659 + dtx_string_box(str, &box); 9.660 + return box.height; 9.661 +} 9.662 + 9.663 +float dtx_char_pos(const char *str, int n) 9.664 +{ 9.665 + int i; 9.666 + float pos = 0.0; 9.667 + struct dtx_glyphmap *gmap; 9.668 + 9.669 + for(i=0; i<n; i++) { 9.670 + int code = dtx_utf8_char_code(str); 9.671 + str = dtx_utf8_next_char((char*)str); 9.672 + 9.673 + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); 9.674 + pos += gmap->glyphs[i].advance; 9.675 + } 9.676 + return pos; 9.677 +} 9.678 + 9.679 +int dtx_char_at_pt(const char *str, float pt) 9.680 +{ 9.681 + int i; 9.682 + float prev_pos = 0.0f, pos = 0.0f; 9.683 + struct dtx_glyphmap *gmap; 9.684 + 9.685 + for(i=0; *str; i++) { 9.686 + int code = dtx_utf8_char_code(str); 9.687 + str = dtx_utf8_next_char((char*)str); 9.688 + 9.689 + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); 9.690 + pos += gmap->glyphs[i].advance; 9.691 + 9.692 + if(fabs(pt - prev_pos) < fabs(pt - pos)) { 9.693 + break; 9.694 + } 9.695 + prev_pos = pos; 9.696 + } 9.697 + return i; 9.698 +} 9.699 + 9.700 +struct dtx_glyphmap *dtx_proc_char(int code, float *xpos, float *ypos) 9.701 +{ 9.702 + struct dtx_glyphmap *gmap; 9.703 + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); 9.704 + 9.705 + switch(code) { 9.706 + case '\n': 9.707 + *xpos = 0.0; 9.708 + if(gmap) { 9.709 + *ypos -= gmap->line_advance; 9.710 + } 9.711 + return 0; 9.712 + 9.713 + case '\t': 9.714 + if(gmap) { 9.715 + *xpos = (fmod(*xpos, 4.0) + 4.0) * gmap->glyphs[0].advance; 9.716 + } 9.717 + return 0; 9.718 + 9.719 + case '\r': 9.720 + *xpos = 0.0; 9.721 + return 0; 9.722 + 9.723 + default: 9.724 + break; 9.725 + } 9.726 + 9.727 + if(gmap) { 9.728 + *xpos += gmap->glyphs[code - gmap->cstart].advance; 9.729 + } 9.730 + return gmap; 9.731 +} 9.732 + 9.733 +#ifdef USE_FREETYPE 9.734 +static void calc_best_size(int total_width, int max_gwidth, int max_gheight, int padding, int pow2, int *imgw, int *imgh) 9.735 +{ 9.736 + int xsz, ysz, num_rows; 9.737 + float aspect; 9.738 + 9.739 + for(xsz=2; xsz<=MAX_IMG_WIDTH; xsz *= 2) { 9.740 + num_rows = total_width / xsz + 1; 9.741 + 9.742 + /* assume worst case, all last glyphs will float to the next line 9.743 + * so let's add extra rows for that. */ 9.744 + num_rows += (padding + (max_gwidth + padding) * num_rows + xsz - 1) / xsz; 9.745 + 9.746 + ysz = num_rows * (max_gheight + padding) + padding; 9.747 + if(pow2) { 9.748 + ysz = next_pow2(ysz); 9.749 + } 9.750 + aspect = (float)xsz / (float)ysz; 9.751 + 9.752 + if(aspect >= 1.0) { 9.753 + break; 9.754 + } 9.755 + } 9.756 + 9.757 + if(xsz > MAX_IMG_WIDTH) { 9.758 + xsz = MAX_IMG_WIDTH; 9.759 + } 9.760 + 9.761 + *imgw = xsz; 9.762 + *imgh = ysz; 9.763 +} 9.764 + 9.765 + 9.766 +static int next_pow2(int x) 9.767 +{ 9.768 + x--; 9.769 + x = (x >> 1) | x; 9.770 + x = (x >> 2) | x; 9.771 + x = (x >> 4) | x; 9.772 + x = (x >> 8) | x; 9.773 + x = (x >> 16) | x; 9.774 + return x + 1; 9.775 +} 9.776 +#endif
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/libs/drawtext/utf8.c Sun May 31 00:40:26 2015 +0300 10.3 @@ -0,0 +1,154 @@ 10.4 +/* 10.5 +libdrawtext - a simple library for fast text rendering in OpenGL 10.6 +Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 10.7 + 10.8 +This program is free software: you can redistribute it and/or modify 10.9 +it under the terms of the GNU Lesser General Public License as published by 10.10 +the Free Software Foundation, either version 3 of the License, or 10.11 +(at your option) any later version. 10.12 + 10.13 +This program is distributed in the hope that it will be useful, 10.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 10.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10.16 +GNU Lesser General Public License for more details. 10.17 + 10.18 +You should have received a copy of the GNU Lesser General Public License 10.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 10.20 +*/ 10.21 +#include "drawtext.h" 10.22 + 10.23 +#define U8_IS_FIRST(x) (((((x) >> 7) & 1) == 0) || ((((x) >> 6) & 3) == 3)) 10.24 + 10.25 +static const char first_mask[] = { 10.26 + 0, 10.27 + 0x7f, /* single byte, 7 bits valid */ 10.28 + 0x1f, /* two-bytes, 5 bits valid */ 10.29 + 0xf, /* three-bytes, 4 bits valid */ 10.30 + 0x7 /* four-bytes, 3 bits valid */ 10.31 +}; 10.32 +static const char first_shift[] = { 0, 7, 5, 4, 3 }; /* see above */ 10.33 + 10.34 +#define CONT_PREFIX 0x80 10.35 +#define CONT_MASK 0x3f 10.36 +#define CONT_SHIFT 6 10.37 + 10.38 +/* last charcodes for 1, 2, 3 or 4-byte utf8 chars */ 10.39 +static const int utf8_lastcode[] = { 0x7f, 0x7ff, 0xfff, 0x1fffff }; 10.40 + 10.41 +#define prefix_mask(x) (~first_mask[x]) 10.42 +#define prefix(x) ((prefix_mask(x) << 1) & 0xff) 10.43 + 10.44 + 10.45 +char *dtx_utf8_next_char(char *str) 10.46 +{ 10.47 + return str + dtx_utf8_nbytes(str); 10.48 +} 10.49 + 10.50 +int dtx_utf8_char_code(const char *str) 10.51 +{ 10.52 + int i, nbytes, shift, code = 0; 10.53 + int mask; 10.54 + 10.55 + if(!U8_IS_FIRST(*str)) { 10.56 + return -1; 10.57 + } 10.58 + 10.59 + nbytes = dtx_utf8_nbytes(str); 10.60 + mask = first_mask[nbytes]; 10.61 + shift = 0; 10.62 + 10.63 + for(i=0; i<nbytes; i++) { 10.64 + if(!*str) { 10.65 + break; 10.66 + } 10.67 + 10.68 + code = (code << shift) | (*str++ & mask); 10.69 + mask = 0x3f; 10.70 + shift = 6; 10.71 + } 10.72 + return code; 10.73 +} 10.74 + 10.75 +int dtx_utf8_nbytes(const char *str) 10.76 +{ 10.77 + int i, numset = 0; 10.78 + int c = *str; 10.79 + 10.80 + if(!U8_IS_FIRST(c)) { 10.81 + for(i=0; !U8_IS_FIRST(str[i]); i++); 10.82 + return i; 10.83 + } 10.84 + 10.85 + /* count the leading 1s */ 10.86 + for(i=0; i<4; i++) { 10.87 + if(((c >> (7 - i)) & 1) == 0) { 10.88 + break; 10.89 + } 10.90 + numset++; 10.91 + } 10.92 + 10.93 + if(!numset) { 10.94 + return 1; 10.95 + } 10.96 + return numset; 10.97 +} 10.98 + 10.99 +int dtx_utf8_char_count(const char *str) 10.100 +{ 10.101 + int n = 0; 10.102 + 10.103 + while(*str) { 10.104 + n++; 10.105 + str = dtx_utf8_next_char((char*)str); 10.106 + } 10.107 + return n; 10.108 +} 10.109 + 10.110 +size_t dtx_utf8_from_char_code(int code, char *buf) 10.111 +{ 10.112 + size_t nbytes = 0; 10.113 + int i; 10.114 + 10.115 + for(i=0; i<4; i++) { 10.116 + if(code <= utf8_lastcode[i]) { 10.117 + nbytes = i + 1; 10.118 + break; 10.119 + } 10.120 + } 10.121 + 10.122 + if(!nbytes && buf) { 10.123 + for(i=0; i<(int)nbytes; i++) { 10.124 + int idx = nbytes - i - 1; 10.125 + int mask, shift, prefix; 10.126 + 10.127 + if(idx > 0) { 10.128 + mask = CONT_MASK; 10.129 + shift = CONT_SHIFT; 10.130 + prefix = CONT_PREFIX; 10.131 + } else { 10.132 + mask = first_mask[nbytes]; 10.133 + shift = first_shift[nbytes]; 10.134 + prefix = prefix(nbytes); 10.135 + } 10.136 + 10.137 + buf[idx] = (code & mask) | (prefix & ~mask); 10.138 + code >>= shift; 10.139 + } 10.140 + } 10.141 + return nbytes; 10.142 +} 10.143 + 10.144 +size_t dtx_utf8_from_string(const wchar_t *str, char *buf) 10.145 +{ 10.146 + size_t nbytes = 0; 10.147 + char *ptr = buf; 10.148 + 10.149 + while(*str) { 10.150 + int cbytes = dtx_utf8_from_char_code(*str++, ptr); 10.151 + if(ptr) { 10.152 + ptr += cbytes; 10.153 + } 10.154 + nbytes += cbytes; 10.155 + } 10.156 + return nbytes; 10.157 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/libs/vmath/basis.cc Sun May 31 00:40:26 2015 +0300 11.3 @@ -0,0 +1,80 @@ 11.4 +/* 11.5 +libvmath - a vector math library 11.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 11.7 + 11.8 +This program is free software: you can redistribute it and/or modify 11.9 +it under the terms of the GNU Lesser General Public License as published 11.10 +by the Free Software Foundation, either version 3 of the License, or 11.11 +(at your option) any later version. 11.12 + 11.13 +This program is distributed in the hope that it will be useful, 11.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 11.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.16 +GNU Lesser General Public License for more details. 11.17 + 11.18 +You should have received a copy of the GNU Lesser General Public License 11.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 11.20 +*/ 11.21 +#include "basis.h" 11.22 +#include "vmath.h" 11.23 + 11.24 +Basis::Basis() 11.25 +{ 11.26 + i = Vector3(1, 0, 0); 11.27 + j = Vector3(0, 1, 0); 11.28 + k = Vector3(0, 0, 1); 11.29 +} 11.30 + 11.31 +Basis::Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k) 11.32 +{ 11.33 + this->i = i; 11.34 + this->j = j; 11.35 + this->k = k; 11.36 +} 11.37 + 11.38 +Basis::Basis(const Vector3 &dir, bool left_handed) 11.39 +{ 11.40 + k = dir; 11.41 + j = Vector3(0, 1, 0); 11.42 + i = cross_product(j, k); 11.43 + j = cross_product(k, i); 11.44 +} 11.45 + 11.46 +/** Rotate with euler angles */ 11.47 +void Basis::rotate(scalar_t x, scalar_t y, scalar_t z) { 11.48 + Matrix4x4 RotMat; 11.49 + RotMat.set_rotation(Vector3(x, y, z)); 11.50 + i.transform(RotMat); 11.51 + j.transform(RotMat); 11.52 + k.transform(RotMat); 11.53 +} 11.54 + 11.55 +/** Rotate by axis-angle specification */ 11.56 +void Basis::rotate(const Vector3 &axis, scalar_t angle) { 11.57 + Quaternion q; 11.58 + q.set_rotation(axis, angle); 11.59 + i.transform(q); 11.60 + j.transform(q); 11.61 + k.transform(q); 11.62 +} 11.63 + 11.64 +/** Rotate with a 4x4 matrix */ 11.65 +void Basis::rotate(const Matrix4x4 &mat) { 11.66 + i.transform(mat); 11.67 + j.transform(mat); 11.68 + k.transform(mat); 11.69 +} 11.70 + 11.71 +/** Rotate with a quaternion */ 11.72 +void Basis::rotate(const Quaternion &quat) { 11.73 + i.transform(quat); 11.74 + j.transform(quat); 11.75 + k.transform(quat); 11.76 +} 11.77 + 11.78 +/** Extract a rotation matrix from the orthogonal basis */ 11.79 +Matrix3x3 Basis::create_rotation_matrix() const { 11.80 + return Matrix3x3( i.x, j.x, k.x, 11.81 + i.y, j.y, k.y, 11.82 + i.z, j.z, k.z); 11.83 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/libs/vmath/basis.h Sun May 31 00:40:26 2015 +0300 12.3 @@ -0,0 +1,57 @@ 12.4 +/* 12.5 +libvmath - a vector math library 12.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 12.7 + 12.8 +This program is free software: you can redistribute it and/or modify 12.9 +it under the terms of the GNU Lesser General Public License as published 12.10 +by the Free Software Foundation, either version 3 of the License, or 12.11 +(at your option) any later version. 12.12 + 12.13 +This program is distributed in the hope that it will be useful, 12.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 12.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.16 +GNU Lesser General Public License for more details. 12.17 + 12.18 +You should have received a copy of the GNU Lesser General Public License 12.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 12.20 +*/ 12.21 + 12.22 +#ifndef VMATH_BASIS_H_ 12.23 +#define VMATH_BASIS_H_ 12.24 + 12.25 +#include "vector.h" 12.26 +#include "matrix.h" 12.27 + 12.28 +enum { 12.29 + LEFT_HANDED, 12.30 + RIGHT_HANDED 12.31 +}; 12.32 + 12.33 +#ifdef __cplusplus 12.34 +extern "C" { 12.35 +#endif /* __cplusplus */ 12.36 + 12.37 +void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k); 12.38 +void basis_matrix_dir(mat4_t res, vec3_t dir); 12.39 + 12.40 +#ifdef __cplusplus 12.41 +} /* extern "C" */ 12.42 + 12.43 +class Basis { 12.44 +public: 12.45 + Vector3 i, j, k; 12.46 + 12.47 + Basis(); 12.48 + Basis(const Vector3 &i, const Vector3 &j, const Vector3 &k); 12.49 + Basis(const Vector3 &dir, bool left_handed = true); 12.50 + 12.51 + void rotate(scalar_t x, scalar_t y, scalar_t z); 12.52 + void rotate(const Vector3 &axis, scalar_t angle); 12.53 + void rotate(const Matrix4x4 &mat); 12.54 + void rotate(const Quaternion &quat); 12.55 + 12.56 + Matrix3x3 create_rotation_matrix() const; 12.57 +}; 12.58 +#endif /* __cplusplus */ 12.59 + 12.60 +#endif /* VMATH_BASIS_H_ */
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/libs/vmath/basis_c.c Sun May 31 00:40:26 2015 +0300 13.3 @@ -0,0 +1,37 @@ 13.4 +/* 13.5 +libvmath - a vector math library 13.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 13.7 + 13.8 +This program is free software: you can redistribute it and/or modify 13.9 +it under the terms of the GNU Lesser General Public License as published 13.10 +by the Free Software Foundation, either version 3 of the License, or 13.11 +(at your option) any later version. 13.12 + 13.13 +This program is distributed in the hope that it will be useful, 13.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 13.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13.16 +GNU Lesser General Public License for more details. 13.17 + 13.18 +You should have received a copy of the GNU Lesser General Public License 13.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 13.20 +*/ 13.21 + 13.22 +#include "basis.h" 13.23 +#include "matrix.h" 13.24 + 13.25 +void basis_matrix(mat4_t res, vec3_t i, vec3_t j, vec3_t k) 13.26 +{ 13.27 + m4_identity(res); 13.28 + m4_set_column(res, v4_cons(i.x, i.y, i.z, 1.0), 0); 13.29 + m4_set_column(res, v4_cons(j.x, j.y, j.z, 1.0), 1); 13.30 + m4_set_column(res, v4_cons(k.x, k.y, k.z, 1.0), 2); 13.31 +} 13.32 + 13.33 +void basis_matrix_dir(mat4_t res, vec3_t dir) 13.34 +{ 13.35 + vec3_t k = v3_normalize(dir); 13.36 + vec3_t j = {0, 1, 0}; 13.37 + vec3_t i = v3_cross(j, k); 13.38 + j = v3_cross(k, i); 13.39 + basis_matrix(res, i, j, k); 13.40 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/libs/vmath/geom.c Sun May 31 00:40:26 2015 +0300 14.3 @@ -0,0 +1,150 @@ 14.4 +/* 14.5 +libvmath - a vector math library 14.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 14.7 + 14.8 +This program is free software: you can redistribute it and/or modify 14.9 +it under the terms of the GNU Lesser General Public License as published 14.10 +by the Free Software Foundation, either version 3 of the License, or 14.11 +(at your option) any later version. 14.12 + 14.13 +This program is distributed in the hope that it will be useful, 14.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 14.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14.16 +GNU Lesser General Public License for more details. 14.17 + 14.18 +You should have received a copy of the GNU Lesser General Public License 14.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 14.20 +*/ 14.21 + 14.22 + 14.23 +#include <math.h> 14.24 +#include "geom.h" 14.25 +#include "vector.h" 14.26 + 14.27 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d) 14.28 +{ 14.29 + plane_t p; 14.30 + p.norm.x = nx; 14.31 + p.norm.y = ny; 14.32 + p.norm.z = nz; 14.33 + p.d = d; 14.34 + return p; 14.35 +} 14.36 + 14.37 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2) 14.38 +{ 14.39 + vec3_t a, b, norm; 14.40 + 14.41 + a = v3_sub(v1, v0); 14.42 + b = v3_sub(v2, v0); 14.43 + norm = v3_cross(a, b); 14.44 + norm = v3_normalize(norm); 14.45 + 14.46 + return plane_ptnorm(v0, norm); 14.47 +} 14.48 + 14.49 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal) 14.50 +{ 14.51 + plane_t plane; 14.52 + 14.53 + plane.norm = normal; 14.54 + plane.d = v3_dot(pt, normal); 14.55 + 14.56 + return plane; 14.57 +} 14.58 + 14.59 +plane_t plane_invert(plane_t p) 14.60 +{ 14.61 + p.norm = v3_neg(p.norm); 14.62 + p.d = -p.d; 14.63 + return p; 14.64 +} 14.65 + 14.66 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt) 14.67 +{ 14.68 + vec3_t pp = plane_point(plane); 14.69 + vec3_t pptopt = v3_sub(pt, pp); 14.70 + return v3_dot(pptopt, plane.norm); 14.71 +} 14.72 + 14.73 +scalar_t plane_dist(plane_t plane, vec3_t pt) 14.74 +{ 14.75 + return fabs(plane_signed_dist(plane, pt)); 14.76 +} 14.77 + 14.78 +vec3_t plane_point(plane_t plane) 14.79 +{ 14.80 + return v3_scale(plane.norm, plane.d); 14.81 +} 14.82 + 14.83 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos) 14.84 +{ 14.85 + vec3_t pt, orig_to_pt; 14.86 + scalar_t ndotdir; 14.87 + 14.88 + pt = plane_point(plane); 14.89 + ndotdir = v3_dot(plane.norm, ray.dir); 14.90 + 14.91 + if(fabs(ndotdir) < 1e-7) { 14.92 + return 0; 14.93 + } 14.94 + 14.95 + if(pos) { 14.96 + orig_to_pt = v3_sub(pt, ray.origin); 14.97 + *pos = v3_dot(plane.norm, orig_to_pt) / ndotdir; 14.98 + } 14.99 + return 1; 14.100 +} 14.101 + 14.102 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad) 14.103 +{ 14.104 + sphere_t sph; 14.105 + sph.pos.x = x; 14.106 + sph.pos.y = y; 14.107 + sph.pos.z = z; 14.108 + sph.rad = rad; 14.109 + return sph; 14.110 +} 14.111 + 14.112 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos) 14.113 +{ 14.114 + scalar_t a, b, c, d, sqrt_d, t1, t2, t; 14.115 + 14.116 + a = v3_dot(ray.dir, ray.dir); 14.117 + b = 2.0 * ray.dir.x * (ray.origin.x - sph.pos.x) + 14.118 + 2.0 * ray.dir.y * (ray.origin.y - sph.pos.y) + 14.119 + 2.0 * ray.dir.z * (ray.origin.z - sph.pos.z); 14.120 + c = v3_dot(sph.pos, sph.pos) + v3_dot(ray.origin, ray.origin) + 14.121 + 2.0 * v3_dot(v3_neg(sph.pos), ray.origin) - sph.rad * sph.rad; 14.122 + 14.123 + d = b * b - 4.0 * a * c; 14.124 + if(d < 0.0) { 14.125 + return 0; 14.126 + } 14.127 + 14.128 + sqrt_d = sqrt(d); 14.129 + t1 = (-b + sqrt_d) / (2.0 * a); 14.130 + t2 = (-b - sqrt_d) / (2.0 * a); 14.131 + 14.132 + if(t1 < 1e-7 || t1 > 1.0) { 14.133 + t1 = t2; 14.134 + } 14.135 + if(t2 < 1e-7 || t2 > 1.0) { 14.136 + t2 = t1; 14.137 + } 14.138 + t = t1 < t2 ? t1 : t2; 14.139 + 14.140 + if(t < 1e-7 || t > 1.0) { 14.141 + return 0; 14.142 + } 14.143 + 14.144 + if(pos) { 14.145 + *pos = t; 14.146 + } 14.147 + return 1; 14.148 +} 14.149 + 14.150 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad) 14.151 +{ 14.152 + return -1; 14.153 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/libs/vmath/geom.h Sun May 31 00:40:26 2015 +0300 15.3 @@ -0,0 +1,72 @@ 15.4 +/* 15.5 +libvmath - a vector math library 15.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 15.7 + 15.8 +This program is free software: you can redistribute it and/or modify 15.9 +it under the terms of the GNU Lesser General Public License as published 15.10 +by the Free Software Foundation, either version 3 of the License, or 15.11 +(at your option) any later version. 15.12 + 15.13 +This program is distributed in the hope that it will be useful, 15.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 15.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15.16 +GNU Lesser General Public License for more details. 15.17 + 15.18 +You should have received a copy of the GNU Lesser General Public License 15.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 15.20 +*/ 15.21 +#ifndef LIBVMATH_GEOM_H_ 15.22 +#define LIBVMATH_GEOM_H_ 15.23 + 15.24 +#include "vector.h" 15.25 +#include "ray.h" 15.26 + 15.27 +typedef struct { 15.28 + vec3_t norm; 15.29 + scalar_t d; 15.30 +} plane_t; 15.31 + 15.32 +typedef struct { 15.33 + vec3_t pos; 15.34 + scalar_t rad; 15.35 +} sphere_t; 15.36 + 15.37 +typedef struct { 15.38 + vec3_t min, max; 15.39 +} aabox_t; 15.40 + 15.41 +#ifdef __cplusplus 15.42 +extern "C" { 15.43 +#endif 15.44 + 15.45 +/* planes are good... you need planes, yes you do */ 15.46 +plane_t plane_cons(scalar_t nx, scalar_t ny, scalar_t nz, scalar_t d); 15.47 +plane_t plane_poly(vec3_t v0, vec3_t v1, vec3_t v2); 15.48 +plane_t plane_ptnorm(vec3_t pt, vec3_t normal); 15.49 + 15.50 +plane_t plane_invert(plane_t p); 15.51 + 15.52 +scalar_t plane_signed_dist(plane_t plane, vec3_t pt); 15.53 +scalar_t plane_dist(plane_t plane, vec3_t pt); 15.54 +vec3_t plane_point(plane_t plane); 15.55 + 15.56 +int plane_ray_intersect(ray_t ray, plane_t plane, scalar_t *pos); 15.57 + 15.58 +/* spheres always come in handy */ 15.59 +sphere_t sphere_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t rad); 15.60 + 15.61 +int sphere_ray_intersect(ray_t ray, sphere_t sph, scalar_t *pos); 15.62 +int sphere_sphere_intersect(sphere_t sph1, sphere_t sph2, scalar_t *pos, scalar_t *rad); 15.63 + 15.64 +#ifdef __cplusplus 15.65 +} 15.66 + 15.67 +/* TODO 15.68 +class Plane : public plane_t { 15.69 +public: 15.70 +}; 15.71 +*/ 15.72 + 15.73 +#endif 15.74 + 15.75 +#endif /* LIBVMATH_GEOM_H_ */
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/libs/vmath/matrix.cc Sun May 31 00:40:26 2015 +0300 16.3 @@ -0,0 +1,872 @@ 16.4 +/* 16.5 +libvmath - a vector math library 16.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 16.7 + 16.8 +This program is free software: you can redistribute it and/or modify 16.9 +it under the terms of the GNU Lesser General Public License as published 16.10 +by the Free Software Foundation, either version 3 of the License, or 16.11 +(at your option) any later version. 16.12 + 16.13 +This program is distributed in the hope that it will be useful, 16.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 16.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16.16 +GNU Lesser General Public License for more details. 16.17 + 16.18 +You should have received a copy of the GNU Lesser General Public License 16.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 16.20 +*/ 16.21 +#include <cstdio> 16.22 +#include <cmath> 16.23 +#include "matrix.h" 16.24 +#include "vector.h" 16.25 +#include "quat.h" 16.26 + 16.27 +using namespace std; 16.28 + 16.29 +// ----------- Matrix3x3 -------------- 16.30 + 16.31 +Matrix3x3 Matrix3x3::identity = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); 16.32 + 16.33 +Matrix3x3::Matrix3x3() 16.34 +{ 16.35 + *this = Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1); 16.36 +} 16.37 + 16.38 +Matrix3x3::Matrix3x3( scalar_t m11, scalar_t m12, scalar_t m13, 16.39 + scalar_t m21, scalar_t m22, scalar_t m23, 16.40 + scalar_t m31, scalar_t m32, scalar_t m33) 16.41 +{ 16.42 + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; 16.43 + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; 16.44 + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; 16.45 +} 16.46 + 16.47 +Matrix3x3::Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec) 16.48 +{ 16.49 + set_row_vector(ivec, 0); 16.50 + set_row_vector(jvec, 1); 16.51 + set_row_vector(kvec, 2); 16.52 +} 16.53 + 16.54 +Matrix3x3::Matrix3x3(const mat3_t cmat) 16.55 +{ 16.56 + memcpy(m, cmat, sizeof(mat3_t)); 16.57 +} 16.58 + 16.59 +Matrix3x3::Matrix3x3(const Matrix4x4 &mat4x4) 16.60 +{ 16.61 + for(int i=0; i<3; i++) { 16.62 + for(int j=0; j<3; j++) { 16.63 + m[i][j] = mat4x4[i][j]; 16.64 + } 16.65 + } 16.66 +} 16.67 + 16.68 +Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2) 16.69 +{ 16.70 + Matrix3x3 res; 16.71 + const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; 16.72 + scalar_t *dest = res.m[0]; 16.73 + 16.74 + for(int i=0; i<9; i++) { 16.75 + *dest++ = *op1++ + *op2++; 16.76 + } 16.77 + return res; 16.78 +} 16.79 + 16.80 +Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2) 16.81 +{ 16.82 + Matrix3x3 res; 16.83 + const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; 16.84 + scalar_t *dest = res.m[0]; 16.85 + 16.86 + for(int i=0; i<9; i++) { 16.87 + *dest++ = *op1++ - *op2++; 16.88 + } 16.89 + return res; 16.90 +} 16.91 + 16.92 +Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2) 16.93 +{ 16.94 + Matrix3x3 res; 16.95 + for(int i=0; i<3; i++) { 16.96 + for(int j=0; j<3; j++) { 16.97 + res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j]; 16.98 + } 16.99 + } 16.100 + return res; 16.101 +} 16.102 + 16.103 +void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2) 16.104 +{ 16.105 + scalar_t *op1 = m1.m[0]; 16.106 + const scalar_t *op2 = m2.m[0]; 16.107 + 16.108 + for(int i=0; i<9; i++) { 16.109 + *op1++ += *op2++; 16.110 + } 16.111 +} 16.112 + 16.113 +void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2) 16.114 +{ 16.115 + scalar_t *op1 = m1.m[0]; 16.116 + const scalar_t *op2 = m2.m[0]; 16.117 + 16.118 + for(int i=0; i<9; i++) { 16.119 + *op1++ -= *op2++; 16.120 + } 16.121 +} 16.122 + 16.123 +void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2) 16.124 +{ 16.125 + Matrix3x3 res; 16.126 + for(int i=0; i<3; i++) { 16.127 + for(int j=0; j<3; j++) { 16.128 + res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j]; 16.129 + } 16.130 + } 16.131 + memcpy(m1.m, res.m, 9 * sizeof(scalar_t)); 16.132 +} 16.133 + 16.134 +Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar) 16.135 +{ 16.136 + Matrix3x3 res; 16.137 + const scalar_t *mptr = mat.m[0]; 16.138 + scalar_t *dptr = res.m[0]; 16.139 + 16.140 + for(int i=0; i<9; i++) { 16.141 + *dptr++ = *mptr++ * scalar; 16.142 + } 16.143 + return res; 16.144 +} 16.145 + 16.146 +Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat) 16.147 +{ 16.148 + Matrix3x3 res; 16.149 + const scalar_t *mptr = mat.m[0]; 16.150 + scalar_t *dptr = res.m[0]; 16.151 + 16.152 + for(int i=0; i<9; i++) { 16.153 + *dptr++ = *mptr++ * scalar; 16.154 + } 16.155 + return res; 16.156 +} 16.157 + 16.158 +void operator *=(Matrix3x3 &mat, scalar_t scalar) 16.159 +{ 16.160 + scalar_t *mptr = mat.m[0]; 16.161 + 16.162 + for(int i=0; i<9; i++) { 16.163 + *mptr++ *= scalar; 16.164 + } 16.165 +} 16.166 + 16.167 +void Matrix3x3::translate(const Vector2 &trans) 16.168 +{ 16.169 + Matrix3x3 tmat(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1); 16.170 + *this *= tmat; 16.171 +} 16.172 + 16.173 +void Matrix3x3::set_translation(const Vector2 &trans) 16.174 +{ 16.175 + *this = Matrix3x3(1, 0, trans.x, 0, 1, trans.y, 0, 0, 1); 16.176 +} 16.177 + 16.178 +void Matrix3x3::rotate(scalar_t angle) 16.179 +{ 16.180 + scalar_t cos_a = cos(angle); 16.181 + scalar_t sin_a = sin(angle); 16.182 + Matrix3x3 rmat( cos_a, -sin_a, 0, 16.183 + sin_a, cos_a, 0, 16.184 + 0, 0, 1); 16.185 + *this *= rmat; 16.186 +} 16.187 + 16.188 +void Matrix3x3::set_rotation(scalar_t angle) 16.189 +{ 16.190 + scalar_t cos_a = cos(angle); 16.191 + scalar_t sin_a = sin(angle); 16.192 + *this = Matrix3x3(cos_a, -sin_a, 0, sin_a, cos_a, 0, 0, 0, 1); 16.193 +} 16.194 + 16.195 +void Matrix3x3::rotate(const Vector3 &euler_angles) 16.196 +{ 16.197 + Matrix3x3 xrot, yrot, zrot; 16.198 + 16.199 + xrot = Matrix3x3( 1, 0, 0, 16.200 + 0, cos(euler_angles.x), -sin(euler_angles.x), 16.201 + 0, sin(euler_angles.x), cos(euler_angles.x)); 16.202 + 16.203 + yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), 16.204 + 0, 1, 0, 16.205 + -sin(euler_angles.y), 0, cos(euler_angles.y)); 16.206 + 16.207 + zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, 16.208 + sin(euler_angles.z), cos(euler_angles.z), 0, 16.209 + 0, 0, 1); 16.210 + 16.211 + *this *= xrot * yrot * zrot; 16.212 +} 16.213 + 16.214 +void Matrix3x3::set_rotation(const Vector3 &euler_angles) 16.215 +{ 16.216 + Matrix3x3 xrot, yrot, zrot; 16.217 + 16.218 + xrot = Matrix3x3( 1, 0, 0, 16.219 + 0, cos(euler_angles.x), -sin(euler_angles.x), 16.220 + 0, sin(euler_angles.x), cos(euler_angles.x)); 16.221 + 16.222 + yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), 16.223 + 0, 1, 0, 16.224 + -sin(euler_angles.y), 0, cos(euler_angles.y)); 16.225 + 16.226 + zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, 16.227 + sin(euler_angles.z), cos(euler_angles.z), 0, 16.228 + 0, 0, 1); 16.229 + 16.230 + *this = xrot * yrot * zrot; 16.231 +} 16.232 + 16.233 +void Matrix3x3::rotate(const Vector3 &axis, scalar_t angle) 16.234 +{ 16.235 + scalar_t sina = (scalar_t)sin(angle); 16.236 + scalar_t cosa = (scalar_t)cos(angle); 16.237 + scalar_t invcosa = 1-cosa; 16.238 + scalar_t nxsq = axis.x * axis.x; 16.239 + scalar_t nysq = axis.y * axis.y; 16.240 + scalar_t nzsq = axis.z * axis.z; 16.241 + 16.242 + Matrix3x3 xform; 16.243 + xform.m[0][0] = nxsq + (1-nxsq) * cosa; 16.244 + xform.m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; 16.245 + xform.m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; 16.246 + 16.247 + xform.m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; 16.248 + xform.m[1][1] = nysq + (1-nysq) * cosa; 16.249 + xform.m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; 16.250 + 16.251 + xform.m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; 16.252 + xform.m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; 16.253 + xform.m[2][2] = nzsq + (1-nzsq) * cosa; 16.254 + 16.255 + *this *= xform; 16.256 +} 16.257 + 16.258 +void Matrix3x3::set_rotation(const Vector3 &axis, scalar_t angle) 16.259 +{ 16.260 + scalar_t sina = (scalar_t)sin(angle); 16.261 + scalar_t cosa = (scalar_t)cos(angle); 16.262 + scalar_t invcosa = 1-cosa; 16.263 + scalar_t nxsq = axis.x * axis.x; 16.264 + scalar_t nysq = axis.y * axis.y; 16.265 + scalar_t nzsq = axis.z * axis.z; 16.266 + 16.267 + reset_identity(); 16.268 + m[0][0] = nxsq + (1-nxsq) * cosa; 16.269 + m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; 16.270 + m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; 16.271 + m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; 16.272 + m[1][1] = nysq + (1-nysq) * cosa; 16.273 + m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; 16.274 + m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; 16.275 + m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; 16.276 + m[2][2] = nzsq + (1-nzsq) * cosa; 16.277 +} 16.278 + 16.279 +// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes 16.280 +// article "Quaternion Calculus and Fast Animation". 16.281 +// adapted from: http://www.geometrictools.com/LibMathematics/Algebra/Wm5Quaternion.inl 16.282 +Quaternion Matrix3x3::get_rotation_quat() const 16.283 +{ 16.284 + static const int next[3] = {1, 2, 0}; 16.285 + 16.286 + float quat[4]; 16.287 + 16.288 + scalar_t trace = m[0][0] + m[1][1] + m[2][2]; 16.289 + scalar_t root; 16.290 + 16.291 + if(trace > 0.0f) { 16.292 + // |w| > 1/2 16.293 + root = sqrt(trace + 1.0f); // 2w 16.294 + quat[0] = 0.5f * root; 16.295 + root = 0.5f / root; // 1 / 4w 16.296 + quat[1] = (m[2][1] - m[1][2]) * root; 16.297 + quat[2] = (m[0][2] - m[2][0]) * root; 16.298 + quat[3] = (m[1][0] - m[0][1]) * root; 16.299 + } else { 16.300 + // |w| <= 1/2 16.301 + int i = 0; 16.302 + if(m[1][1] > m[0][0]) { 16.303 + i = 1; 16.304 + } 16.305 + if(m[2][2] > m[i][i]) { 16.306 + i = 2; 16.307 + } 16.308 + int j = next[i]; 16.309 + int k = next[j]; 16.310 + 16.311 + root = sqrt(m[i][i] - m[j][j] - m[k][k] + 1.0f); 16.312 + quat[i + 1] = 0.5f * root; 16.313 + root = 0.5f / root; 16.314 + quat[0] = (m[k][j] - m[j][k]) * root; 16.315 + quat[j + 1] = (m[j][i] - m[i][j]) * root; 16.316 + quat[k + 1] = (m[k][i] - m[i][k]) * root; 16.317 + } 16.318 + return Quaternion(quat[0], quat[1], quat[2], quat[3]); 16.319 +} 16.320 + 16.321 +void Matrix3x3::scale(const Vector3 &scale_vec) 16.322 +{ 16.323 + Matrix3x3 smat( scale_vec.x, 0, 0, 16.324 + 0, scale_vec.y, 0, 16.325 + 0, 0, scale_vec.z); 16.326 + *this *= smat; 16.327 +} 16.328 + 16.329 +void Matrix3x3::set_scaling(const Vector3 &scale_vec) 16.330 +{ 16.331 + *this = Matrix3x3( scale_vec.x, 0, 0, 16.332 + 0, scale_vec.y, 0, 16.333 + 0, 0, scale_vec.z); 16.334 +} 16.335 + 16.336 +void Matrix3x3::set_column_vector(const Vector3 &vec, unsigned int col_index) 16.337 +{ 16.338 + m[0][col_index] = vec.x; 16.339 + m[1][col_index] = vec.y; 16.340 + m[2][col_index] = vec.z; 16.341 +} 16.342 + 16.343 +void Matrix3x3::set_row_vector(const Vector3 &vec, unsigned int row_index) 16.344 +{ 16.345 + m[row_index][0] = vec.x; 16.346 + m[row_index][1] = vec.y; 16.347 + m[row_index][2] = vec.z; 16.348 +} 16.349 + 16.350 +Vector3 Matrix3x3::get_column_vector(unsigned int col_index) const 16.351 +{ 16.352 + return Vector3(m[0][col_index], m[1][col_index], m[2][col_index]); 16.353 +} 16.354 + 16.355 +Vector3 Matrix3x3::get_row_vector(unsigned int row_index) const 16.356 +{ 16.357 + return Vector3(m[row_index][0], m[row_index][1], m[row_index][2]); 16.358 +} 16.359 + 16.360 +void Matrix3x3::transpose() 16.361 +{ 16.362 + Matrix3x3 tmp = *this; 16.363 + for(int i=0; i<3; i++) { 16.364 + for(int j=0; j<3; j++) { 16.365 + m[i][j] = tmp[j][i]; 16.366 + } 16.367 + } 16.368 +} 16.369 + 16.370 +Matrix3x3 Matrix3x3::transposed() const 16.371 +{ 16.372 + Matrix3x3 res; 16.373 + for(int i=0; i<3; i++) { 16.374 + for(int j=0; j<3; j++) { 16.375 + res[i][j] = m[j][i]; 16.376 + } 16.377 + } 16.378 + return res; 16.379 +} 16.380 + 16.381 +scalar_t Matrix3x3::determinant() const 16.382 +{ 16.383 + return m[0][0] * (m[1][1]*m[2][2] - m[1][2]*m[2][1]) - 16.384 + m[0][1] * (m[1][0]*m[2][2] - m[1][2]*m[2][0]) + 16.385 + m[0][2] * (m[1][0]*m[2][1] - m[1][1]*m[2][0]); 16.386 +} 16.387 + 16.388 +Matrix3x3 Matrix3x3::inverse() const 16.389 +{ 16.390 + // TODO: implement 3x3 inverse 16.391 + return *this; 16.392 +} 16.393 + 16.394 +/*ostream &operator <<(ostream &out, const Matrix3x3 &mat) 16.395 +{ 16.396 + for(int i=0; i<3; i++) { 16.397 + char str[100]; 16.398 + sprintf(str, "[ %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2]); 16.399 + out << str; 16.400 + } 16.401 + return out; 16.402 +}*/ 16.403 + 16.404 + 16.405 + 16.406 +/* ----------------- Matrix4x4 implementation --------------- */ 16.407 + 16.408 +Matrix4x4 Matrix4x4::identity = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); 16.409 + 16.410 +Matrix4x4::Matrix4x4() 16.411 +{ 16.412 + *this = Matrix4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); 16.413 +} 16.414 + 16.415 +Matrix4x4::Matrix4x4( scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, 16.416 + scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, 16.417 + scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, 16.418 + scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44) 16.419 +{ 16.420 + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14; 16.421 + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24; 16.422 + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34; 16.423 + m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44; 16.424 +} 16.425 + 16.426 +Matrix4x4::Matrix4x4(const mat4_t cmat) 16.427 +{ 16.428 + memcpy(m, cmat, sizeof(mat4_t)); 16.429 +} 16.430 + 16.431 +Matrix4x4::Matrix4x4(const Matrix3x3 &mat3x3) 16.432 +{ 16.433 + reset_identity(); 16.434 + for(int i=0; i<3; i++) { 16.435 + for(int j=0; j<3; j++) { 16.436 + m[i][j] = mat3x3[i][j]; 16.437 + } 16.438 + } 16.439 +} 16.440 + 16.441 +Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2) 16.442 +{ 16.443 + Matrix4x4 res; 16.444 + const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; 16.445 + scalar_t *dest = res.m[0]; 16.446 + 16.447 + for(int i=0; i<16; i++) { 16.448 + *dest++ = *op1++ + *op2++; 16.449 + } 16.450 + return res; 16.451 +} 16.452 + 16.453 +Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2) 16.454 +{ 16.455 + Matrix4x4 res; 16.456 + const scalar_t *op1 = m1.m[0], *op2 = m2.m[0]; 16.457 + scalar_t *dest = res.m[0]; 16.458 + 16.459 + for(int i=0; i<16; i++) { 16.460 + *dest++ = *op1++ - *op2++; 16.461 + } 16.462 + return res; 16.463 +} 16.464 + 16.465 +void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2) 16.466 +{ 16.467 + scalar_t *op1 = m1.m[0]; 16.468 + const scalar_t *op2 = m2.m[0]; 16.469 + 16.470 + for(int i=0; i<16; i++) { 16.471 + *op1++ += *op2++; 16.472 + } 16.473 +} 16.474 + 16.475 +void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2) 16.476 +{ 16.477 + scalar_t *op1 = m1.m[0]; 16.478 + const scalar_t *op2 = m2.m[0]; 16.479 + 16.480 + for(int i=0; i<16; i++) { 16.481 + *op1++ -= *op2++; 16.482 + } 16.483 +} 16.484 + 16.485 +Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar) 16.486 +{ 16.487 + Matrix4x4 res; 16.488 + const scalar_t *mptr = mat.m[0]; 16.489 + scalar_t *dptr = res.m[0]; 16.490 + 16.491 + for(int i=0; i<16; i++) { 16.492 + *dptr++ = *mptr++ * scalar; 16.493 + } 16.494 + return res; 16.495 +} 16.496 + 16.497 +Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat) 16.498 +{ 16.499 + Matrix4x4 res; 16.500 + const scalar_t *mptr = mat.m[0]; 16.501 + scalar_t *dptr = res.m[0]; 16.502 + 16.503 + for(int i=0; i<16; i++) { 16.504 + *dptr++ = *mptr++ * scalar; 16.505 + } 16.506 + return res; 16.507 +} 16.508 + 16.509 +void operator *=(Matrix4x4 &mat, scalar_t scalar) 16.510 +{ 16.511 + scalar_t *mptr = mat.m[0]; 16.512 + 16.513 + for(int i=0; i<16; i++) { 16.514 + *mptr++ *= scalar; 16.515 + } 16.516 +} 16.517 + 16.518 +void Matrix4x4::translate(const Vector3 &trans) 16.519 +{ 16.520 + Matrix4x4 tmat(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1); 16.521 + *this *= tmat; 16.522 +} 16.523 + 16.524 +void Matrix4x4::set_translation(const Vector3 &trans) 16.525 +{ 16.526 + *this = Matrix4x4(1, 0, 0, trans.x, 0, 1, 0, trans.y, 0, 0, 1, trans.z, 0, 0, 0, 1); 16.527 +} 16.528 + 16.529 +Vector3 Matrix4x4::get_translation() const 16.530 +{ 16.531 + return Vector3(m[0][3], m[1][3], m[2][3]); 16.532 +} 16.533 + 16.534 +void Matrix4x4::rotate(const Vector3 &euler_angles) 16.535 +{ 16.536 + Matrix3x3 xrot, yrot, zrot; 16.537 + 16.538 + xrot = Matrix3x3( 1, 0, 0, 16.539 + 0, cos(euler_angles.x), -sin(euler_angles.x), 16.540 + 0, sin(euler_angles.x), cos(euler_angles.x)); 16.541 + 16.542 + yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), 16.543 + 0, 1, 0, 16.544 + -sin(euler_angles.y), 0, cos(euler_angles.y)); 16.545 + 16.546 + zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, 16.547 + sin(euler_angles.z), cos(euler_angles.z), 0, 16.548 + 0, 0, 1); 16.549 + 16.550 + *this *= Matrix4x4(xrot * yrot * zrot); 16.551 +} 16.552 + 16.553 +void Matrix4x4::set_rotation(const Vector3 &euler_angles) 16.554 +{ 16.555 + Matrix3x3 xrot, yrot, zrot; 16.556 + 16.557 + xrot = Matrix3x3( 1, 0, 0, 16.558 + 0, cos(euler_angles.x), -sin(euler_angles.x), 16.559 + 0, sin(euler_angles.x), cos(euler_angles.x)); 16.560 + 16.561 + yrot = Matrix3x3( cos(euler_angles.y), 0, sin(euler_angles.y), 16.562 + 0, 1, 0, 16.563 + -sin(euler_angles.y), 0, cos(euler_angles.y)); 16.564 + 16.565 + zrot = Matrix3x3( cos(euler_angles.z), -sin(euler_angles.z), 0, 16.566 + sin(euler_angles.z), cos(euler_angles.z), 0, 16.567 + 0, 0, 1); 16.568 + 16.569 + *this = Matrix4x4(xrot * yrot * zrot); 16.570 +} 16.571 + 16.572 +void Matrix4x4::rotate(const Vector3 &axis, scalar_t angle) 16.573 +{ 16.574 + scalar_t sina = (scalar_t)sin(angle); 16.575 + scalar_t cosa = (scalar_t)cos(angle); 16.576 + scalar_t invcosa = 1-cosa; 16.577 + scalar_t nxsq = axis.x * axis.x; 16.578 + scalar_t nysq = axis.y * axis.y; 16.579 + scalar_t nzsq = axis.z * axis.z; 16.580 + 16.581 + Matrix4x4 xform; 16.582 + xform[0][0] = nxsq + (1-nxsq) * cosa; 16.583 + xform[0][1] = axis.x * axis.y * invcosa - axis.z * sina; 16.584 + xform[0][2] = axis.x * axis.z * invcosa + axis.y * sina; 16.585 + xform[1][0] = axis.x * axis.y * invcosa + axis.z * sina; 16.586 + xform[1][1] = nysq + (1-nysq) * cosa; 16.587 + xform[1][2] = axis.y * axis.z * invcosa - axis.x * sina; 16.588 + xform[2][0] = axis.x * axis.z * invcosa - axis.y * sina; 16.589 + xform[2][1] = axis.y * axis.z * invcosa + axis.x * sina; 16.590 + xform[2][2] = nzsq + (1-nzsq) * cosa; 16.591 + 16.592 + *this *= xform; 16.593 +} 16.594 + 16.595 +void Matrix4x4::set_rotation(const Vector3 &axis, scalar_t angle) 16.596 +{ 16.597 + scalar_t sina = (scalar_t)sin(angle); 16.598 + scalar_t cosa = (scalar_t)cos(angle); 16.599 + scalar_t invcosa = 1-cosa; 16.600 + scalar_t nxsq = axis.x * axis.x; 16.601 + scalar_t nysq = axis.y * axis.y; 16.602 + scalar_t nzsq = axis.z * axis.z; 16.603 + 16.604 + reset_identity(); 16.605 + m[0][0] = nxsq + (1-nxsq) * cosa; 16.606 + m[0][1] = axis.x * axis.y * invcosa - axis.z * sina; 16.607 + m[0][2] = axis.x * axis.z * invcosa + axis.y * sina; 16.608 + m[1][0] = axis.x * axis.y * invcosa + axis.z * sina; 16.609 + m[1][1] = nysq + (1-nysq) * cosa; 16.610 + m[1][2] = axis.y * axis.z * invcosa - axis.x * sina; 16.611 + m[2][0] = axis.x * axis.z * invcosa - axis.y * sina; 16.612 + m[2][1] = axis.y * axis.z * invcosa + axis.x * sina; 16.613 + m[2][2] = nzsq + (1-nzsq) * cosa; 16.614 +} 16.615 + 16.616 +void Matrix4x4::rotate(const Quaternion &quat) 16.617 +{ 16.618 + *this *= quat.get_rotation_matrix(); 16.619 +} 16.620 + 16.621 +void Matrix4x4::set_rotation(const Quaternion &quat) 16.622 +{ 16.623 + *this = quat.get_rotation_matrix(); 16.624 +} 16.625 + 16.626 +Quaternion Matrix4x4::get_rotation_quat() const 16.627 +{ 16.628 + Matrix3x3 mat3 = *this; 16.629 + return mat3.get_rotation_quat(); 16.630 +} 16.631 + 16.632 +void Matrix4x4::scale(const Vector4 &scale_vec) 16.633 +{ 16.634 + Matrix4x4 smat( scale_vec.x, 0, 0, 0, 16.635 + 0, scale_vec.y, 0, 0, 16.636 + 0, 0, scale_vec.z, 0, 16.637 + 0, 0, 0, scale_vec.w); 16.638 + *this *= smat; 16.639 +} 16.640 + 16.641 +void Matrix4x4::set_scaling(const Vector4 &scale_vec) 16.642 +{ 16.643 + *this = Matrix4x4( scale_vec.x, 0, 0, 0, 16.644 + 0, scale_vec.y, 0, 0, 16.645 + 0, 0, scale_vec.z, 0, 16.646 + 0, 0, 0, scale_vec.w); 16.647 +} 16.648 + 16.649 +Vector3 Matrix4x4::get_scaling() const 16.650 +{ 16.651 + Vector3 vi = get_row_vector(0); 16.652 + Vector3 vj = get_row_vector(1); 16.653 + Vector3 vk = get_row_vector(2); 16.654 + 16.655 + return Vector3(vi.length(), vj.length(), vk.length()); 16.656 +} 16.657 + 16.658 +void Matrix4x4::set_frustum(float left, float right, float bottom, float top, float znear, float zfar) 16.659 +{ 16.660 + float dx = right - left; 16.661 + float dy = top - bottom; 16.662 + float dz = zfar - znear; 16.663 + 16.664 + float a = (right + left) / dx; 16.665 + float b = (top + bottom) / dy; 16.666 + float c = -(zfar + znear) / dz; 16.667 + float d = -2.0 * zfar * znear / dz; 16.668 + 16.669 + *this = Matrix4x4(2.0 * znear / dx, 0, a, 0, 16.670 + 0, 2.0 * znear / dy, b, 0, 16.671 + 0, 0, c, d, 16.672 + 0, 0, -1, 0); 16.673 +} 16.674 + 16.675 +void Matrix4x4::set_perspective(float vfov, float aspect, float znear, float zfar) 16.676 +{ 16.677 + float f = 1.0f / tan(vfov * 0.5f); 16.678 + float dz = znear - zfar; 16.679 + 16.680 + reset_identity(); 16.681 + 16.682 + m[0][0] = f / aspect; 16.683 + m[1][1] = f; 16.684 + m[2][2] = (zfar + znear) / dz; 16.685 + m[3][2] = -1.0f; 16.686 + m[2][3] = 2.0f * zfar * znear / dz; 16.687 + m[3][3] = 0.0f; 16.688 +} 16.689 + 16.690 +void Matrix4x4::set_orthographic(float left, float right, float bottom, float top, float znear, float zfar) 16.691 +{ 16.692 + float dx = right - left; 16.693 + float dy = top - bottom; 16.694 + float dz = zfar - znear; 16.695 + 16.696 + reset_identity(); 16.697 + 16.698 + m[0][0] = 2.0 / dx; 16.699 + m[1][1] = 2.0 / dy; 16.700 + m[2][2] = -2.0 / dz; 16.701 + m[0][3] = -(right + left) / dx; 16.702 + m[1][3] = -(top + bottom) / dy; 16.703 + m[2][3] = -(zfar + znear) / dz; 16.704 +} 16.705 + 16.706 +void Matrix4x4::set_lookat(const Vector3 &pos, const Vector3 &targ, const Vector3 &up) 16.707 +{ 16.708 + Vector3 vk = (targ - pos).normalized(); 16.709 + Vector3 vj = up.normalized(); 16.710 + Vector3 vi = cross_product(vk, vj).normalized(); 16.711 + vj = cross_product(vi, vk); 16.712 + 16.713 + *this = Matrix4x4( 16.714 + vi.x, vi.y, vi.z, 0, 16.715 + vj.x, vj.y, vj.z, 0, 16.716 + -vk.x, -vk.y, -vk.z, 0, 16.717 + 0, 0, 0, 1); 16.718 + translate(-pos); 16.719 +} 16.720 + 16.721 +void Matrix4x4::set_column_vector(const Vector4 &vec, unsigned int col_index) 16.722 +{ 16.723 + m[0][col_index] = vec.x; 16.724 + m[1][col_index] = vec.y; 16.725 + m[2][col_index] = vec.z; 16.726 + m[3][col_index] = vec.w; 16.727 +} 16.728 + 16.729 +void Matrix4x4::set_row_vector(const Vector4 &vec, unsigned int row_index) 16.730 +{ 16.731 + m[row_index][0] = vec.x; 16.732 + m[row_index][1] = vec.y; 16.733 + m[row_index][2] = vec.z; 16.734 + m[row_index][3] = vec.w; 16.735 +} 16.736 + 16.737 +Vector4 Matrix4x4::get_column_vector(unsigned int col_index) const 16.738 +{ 16.739 + return Vector4(m[0][col_index], m[1][col_index], m[2][col_index], m[3][col_index]); 16.740 +} 16.741 + 16.742 +Vector4 Matrix4x4::get_row_vector(unsigned int row_index) const 16.743 +{ 16.744 + return Vector4(m[row_index][0], m[row_index][1], m[row_index][2], m[row_index][3]); 16.745 +} 16.746 + 16.747 +void Matrix4x4::transpose() 16.748 +{ 16.749 + Matrix4x4 tmp = *this; 16.750 + for(int i=0; i<4; i++) { 16.751 + for(int j=0; j<4; j++) { 16.752 + m[i][j] = tmp[j][i]; 16.753 + } 16.754 + } 16.755 +} 16.756 + 16.757 +Matrix4x4 Matrix4x4::transposed() const 16.758 +{ 16.759 + Matrix4x4 res; 16.760 + for(int i=0; i<4; i++) { 16.761 + for(int j=0; j<4; j++) { 16.762 + res[i][j] = m[j][i]; 16.763 + } 16.764 + } 16.765 + return res; 16.766 +} 16.767 + 16.768 +scalar_t Matrix4x4::determinant() const 16.769 +{ 16.770 + scalar_t det11 = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 16.771 + (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 16.772 + (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 16.773 + 16.774 + scalar_t det12 = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 16.775 + (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 16.776 + (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 16.777 + 16.778 + scalar_t det13 = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 16.779 + (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 16.780 + (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 16.781 + 16.782 + scalar_t det14 = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 16.783 + (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 16.784 + (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 16.785 + 16.786 + return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14; 16.787 +} 16.788 + 16.789 + 16.790 +Matrix4x4 Matrix4x4::adjoint() const 16.791 +{ 16.792 + Matrix4x4 coef; 16.793 + 16.794 + coef.m[0][0] = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 16.795 + (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 16.796 + (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 16.797 + coef.m[0][1] = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 16.798 + (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 16.799 + (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 16.800 + coef.m[0][2] = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 16.801 + (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 16.802 + (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 16.803 + coef.m[0][3] = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 16.804 + (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 16.805 + (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 16.806 + 16.807 + coef.m[1][0] = (m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 16.808 + (m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 16.809 + (m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 16.810 + coef.m[1][1] = (m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 16.811 + (m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 16.812 + (m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 16.813 + coef.m[1][2] = (m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 16.814 + (m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 16.815 + (m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 16.816 + coef.m[1][3] = (m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 16.817 + (m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 16.818 + (m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 16.819 + 16.820 + coef.m[2][0] = (m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - 16.821 + (m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) + 16.822 + (m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])); 16.823 + coef.m[2][1] = (m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - 16.824 + (m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + 16.825 + (m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])); 16.826 + coef.m[2][2] = (m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) - 16.827 + (m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + 16.828 + (m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); 16.829 + coef.m[2][3] = (m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) - 16.830 + (m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) + 16.831 + (m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); 16.832 + 16.833 + coef.m[3][0] = (m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - 16.834 + (m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) + 16.835 + (m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])); 16.836 + coef.m[3][1] = (m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - 16.837 + (m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + 16.838 + (m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])); 16.839 + coef.m[3][2] = (m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) - 16.840 + (m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + 16.841 + (m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); 16.842 + coef.m[3][3] = (m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) - 16.843 + (m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) + 16.844 + (m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); 16.845 + 16.846 + coef.transpose(); 16.847 + 16.848 + for(int i=0; i<4; i++) { 16.849 + for(int j=0; j<4; j++) { 16.850 + coef.m[i][j] = j%2 ? -coef.m[i][j] : coef.m[i][j]; 16.851 + if(i%2) coef.m[i][j] = -coef.m[i][j]; 16.852 + } 16.853 + } 16.854 + 16.855 + return coef; 16.856 +} 16.857 + 16.858 +Matrix4x4 Matrix4x4::inverse() const 16.859 +{ 16.860 + Matrix4x4 adj = adjoint(); 16.861 + 16.862 + return adj * (1.0f / determinant()); 16.863 +} 16.864 + 16.865 +/* 16.866 +ostream &operator <<(ostream &out, const Matrix4x4 &mat) 16.867 +{ 16.868 + for(int i=0; i<4; i++) { 16.869 + char str[100]; 16.870 + sprintf(str, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)mat.m[i][0], (float)mat.m[i][1], (float)mat.m[i][2], (float)mat.m[i][3]); 16.871 + out << str; 16.872 + } 16.873 + return out; 16.874 +} 16.875 +*/
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/libs/vmath/matrix.h Sun May 31 00:40:26 2015 +0300 17.3 @@ -0,0 +1,255 @@ 17.4 +/* 17.5 +libvmath - a vector math library 17.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 17.7 + 17.8 +This program is free software: you can redistribute it and/or modify 17.9 +it under the terms of the GNU Lesser General Public License as published 17.10 +by the Free Software Foundation, either version 3 of the License, or 17.11 +(at your option) any later version. 17.12 + 17.13 +This program is distributed in the hope that it will be useful, 17.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 17.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17.16 +GNU Lesser General Public License for more details. 17.17 + 17.18 +You should have received a copy of the GNU Lesser General Public License 17.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 17.20 +*/ 17.21 + 17.22 +#ifndef VMATH_MATRIX_H_ 17.23 +#define VMATH_MATRIX_H_ 17.24 + 17.25 +#include <stdio.h> 17.26 +#include "vmath_types.h" 17.27 +#include "vector.h" 17.28 + 17.29 +#ifdef __cplusplus 17.30 +extern "C" { 17.31 +#endif /* __cplusplus */ 17.32 + 17.33 +/* C matrix 3x3 functions */ 17.34 +static inline void m3_identity(mat3_t m); 17.35 +static inline void m3_cons(mat3_t m, 17.36 + scalar_t m11, scalar_t m12, scalar_t m13, 17.37 + scalar_t m21, scalar_t m22, scalar_t m23, 17.38 + scalar_t m31, scalar_t m32, scalar_t m33); 17.39 +static inline void m3_copy(mat3_t dest, mat3_t src); 17.40 +void m3_to_m4(mat4_t dest, mat3_t src); 17.41 + 17.42 +void m3_print(FILE *fp, mat3_t m); 17.43 + 17.44 +/* C matrix 4x4 functions */ 17.45 +static inline void m4_identity(mat4_t m); 17.46 +static inline void m4_cons(mat4_t m, 17.47 + scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, 17.48 + scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, 17.49 + scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, 17.50 + scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44); 17.51 +static inline void m4_copy(mat4_t dest, mat4_t src); 17.52 +void m4_to_m3(mat3_t dest, mat4_t src); 17.53 + 17.54 +static inline void m4_mult(mat4_t res, mat4_t m1, mat4_t m2); 17.55 + 17.56 +void m4_set_translation(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 17.57 +void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 17.58 + 17.59 +void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 17.60 + 17.61 +void m4_set_rotation_x(mat4_t m, scalar_t angle); 17.62 +void m4_rotate_x(mat4_t m, scalar_t angle); 17.63 +void m4_set_rotation_y(mat4_t m, scalar_t angle); 17.64 +void m4_rotate_y(mat4_t m, scalar_t angle); 17.65 +void m4_set_rotation_z(mat4_t m, scalar_t angle); 17.66 +void m4_rotate_z(mat4_t m, scalar_t angle); 17.67 +/* axis-angle rotation */ 17.68 +void m4_set_rotation_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); 17.69 +void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); 17.70 +/* concatentate a rotation quaternion */ 17.71 +void m4_rotate_quat(mat4_t m, quat_t q); 17.72 + 17.73 +void m4_set_scaling(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 17.74 +void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z); 17.75 + 17.76 +static inline void m4_set_column(mat4_t m, vec4_t v, int idx); 17.77 +static inline void m4_set_row(mat4_t m, vec4_t v, int idx); 17.78 + 17.79 +void m4_transpose(mat4_t res, mat4_t m); 17.80 +scalar_t m4_determinant(mat4_t m); 17.81 +void m4_adjoint(mat4_t res, mat4_t m); 17.82 +void m4_inverse(mat4_t res, mat4_t m); 17.83 + 17.84 +void m4_print(FILE *fp, mat4_t m); 17.85 + 17.86 +#ifdef __cplusplus 17.87 +} 17.88 + 17.89 +/* when included from C++ source files, also define the matrix classes */ 17.90 + 17.91 +/** 3x3 matrix */ 17.92 +class Matrix3x3 { 17.93 +public: 17.94 + scalar_t m[3][3]; 17.95 + 17.96 + static Matrix3x3 identity; 17.97 + 17.98 + Matrix3x3(); 17.99 + Matrix3x3( scalar_t m11, scalar_t m12, scalar_t m13, 17.100 + scalar_t m21, scalar_t m22, scalar_t m23, 17.101 + scalar_t m31, scalar_t m32, scalar_t m33); 17.102 + Matrix3x3(const Vector3 &ivec, const Vector3 &jvec, const Vector3 &kvec); 17.103 + Matrix3x3(const mat3_t cmat); 17.104 + 17.105 + Matrix3x3(const Matrix4x4 &mat4x4); 17.106 + 17.107 + /* binary operations matrix (op) matrix */ 17.108 + friend Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2); 17.109 + friend Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2); 17.110 + friend Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2); 17.111 + 17.112 + friend void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2); 17.113 + friend void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2); 17.114 + friend void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2); 17.115 + 17.116 + /* binary operations matrix (op) scalar and scalar (op) matrix */ 17.117 + friend Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar); 17.118 + friend Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat); 17.119 + 17.120 + friend void operator *=(Matrix3x3 &mat, scalar_t scalar); 17.121 + 17.122 + inline scalar_t *operator [](int index); 17.123 + inline const scalar_t *operator [](int index) const; 17.124 + 17.125 + inline void reset_identity(); 17.126 + 17.127 + void translate(const Vector2 &trans); 17.128 + void set_translation(const Vector2 &trans); 17.129 + 17.130 + void rotate(scalar_t angle); /* 2d rotation */ 17.131 + void rotate(const Vector3 &euler_angles); /* 3d rotation with euler angles */ 17.132 + void rotate(const Vector3 &axis, scalar_t angle); /* 3d axis/angle rotation */ 17.133 + void set_rotation(scalar_t angle); 17.134 + void set_rotation(const Vector3 &euler_angles); 17.135 + void set_rotation(const Vector3 &axis, scalar_t angle); 17.136 + Quaternion get_rotation_quat() const; 17.137 + 17.138 + void scale(const Vector3 &scale_vec); 17.139 + void set_scaling(const Vector3 &scale_vec); 17.140 + 17.141 + void set_column_vector(const Vector3 &vec, unsigned int col_index); 17.142 + void set_row_vector(const Vector3 &vec, unsigned int row_index); 17.143 + Vector3 get_column_vector(unsigned int col_index) const; 17.144 + Vector3 get_row_vector(unsigned int row_index) const; 17.145 + 17.146 + void transpose(); 17.147 + Matrix3x3 transposed() const; 17.148 + scalar_t determinant() const; 17.149 + Matrix3x3 inverse() const; 17.150 +}; 17.151 + 17.152 +/* binary operations matrix (op) matrix */ 17.153 +Matrix3x3 operator +(const Matrix3x3 &m1, const Matrix3x3 &m2); 17.154 +Matrix3x3 operator -(const Matrix3x3 &m1, const Matrix3x3 &m2); 17.155 +Matrix3x3 operator *(const Matrix3x3 &m1, const Matrix3x3 &m2); 17.156 + 17.157 +void operator +=(Matrix3x3 &m1, const Matrix3x3 &m2); 17.158 +void operator -=(Matrix3x3 &m1, const Matrix3x3 &m2); 17.159 +void operator *=(Matrix3x3 &m1, const Matrix3x3 &m2); 17.160 + 17.161 +/* binary operations matrix (op) scalar and scalar (op) matrix */ 17.162 +Matrix3x3 operator *(const Matrix3x3 &mat, scalar_t scalar); 17.163 +Matrix3x3 operator *(scalar_t scalar, const Matrix3x3 &mat); 17.164 + 17.165 +void operator *=(Matrix3x3 &mat, scalar_t scalar); 17.166 + 17.167 + 17.168 + 17.169 +/** 4x4 matrix */ 17.170 +class Matrix4x4 { 17.171 +public: 17.172 + scalar_t m[4][4]; 17.173 + 17.174 + static Matrix4x4 identity; 17.175 + 17.176 + Matrix4x4(); 17.177 + Matrix4x4( scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, 17.178 + scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, 17.179 + scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, 17.180 + scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44); 17.181 + Matrix4x4(const mat4_t cmat); 17.182 + 17.183 + Matrix4x4(const Matrix3x3 &mat3x3); 17.184 + 17.185 + /* binary operations matrix (op) matrix */ 17.186 + friend Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2); 17.187 + friend Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2); 17.188 + friend Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2); 17.189 + 17.190 + friend void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2); 17.191 + friend void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2); 17.192 + friend inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2); 17.193 + 17.194 + /* binary operations matrix (op) scalar and scalar (op) matrix */ 17.195 + friend Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar); 17.196 + friend Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat); 17.197 + 17.198 + friend void operator *=(Matrix4x4 &mat, scalar_t scalar); 17.199 + 17.200 + inline scalar_t *operator [](int index); 17.201 + inline const scalar_t *operator [](int index) const; 17.202 + 17.203 + inline void reset_identity(); 17.204 + 17.205 + void translate(const Vector3 &trans); 17.206 + void set_translation(const Vector3 &trans); 17.207 + Vector3 get_translation() const; /* extract translation */ 17.208 + 17.209 + void rotate(const Vector3 &euler_angles); /* 3d rotation with euler angles */ 17.210 + void rotate(const Vector3 &axis, scalar_t angle); /* 3d axis/angle rotation */ 17.211 + void rotate(const Quaternion &quat); 17.212 + void set_rotation(const Vector3 &euler_angles); 17.213 + void set_rotation(const Vector3 &axis, scalar_t angle); 17.214 + void set_rotation(const Quaternion &quat); 17.215 + Quaternion get_rotation_quat() const; /* extract rotation */ 17.216 + 17.217 + void scale(const Vector4 &scale_vec); 17.218 + void set_scaling(const Vector4 &scale_vec); 17.219 + Vector3 get_scaling() const; /* extract scaling */ 17.220 + 17.221 + void set_frustum(float left, float right, float top, float bottom, float znear, float zfar); 17.222 + void set_perspective(float vfov, float aspect, float znear, float zfar); 17.223 + void set_orthographic(float left, float right, float bottom, float top, float znear = -1.0, float zfar = 1.0); 17.224 + 17.225 + void set_lookat(const Vector3 &pos, const Vector3 &targ = Vector3(0, 0, 0), const Vector3 &up = Vector3(0, 1, 0)); 17.226 + 17.227 + void set_column_vector(const Vector4 &vec, unsigned int col_index); 17.228 + void set_row_vector(const Vector4 &vec, unsigned int row_index); 17.229 + Vector4 get_column_vector(unsigned int col_index) const; 17.230 + Vector4 get_row_vector(unsigned int row_index) const; 17.231 + 17.232 + void transpose(); 17.233 + Matrix4x4 transposed() const; 17.234 + scalar_t determinant() const; 17.235 + Matrix4x4 adjoint() const; 17.236 + Matrix4x4 inverse() const; 17.237 +}; 17.238 + 17.239 +/* binary operations matrix (op) matrix */ 17.240 +Matrix4x4 operator +(const Matrix4x4 &m1, const Matrix4x4 &m2); 17.241 +Matrix4x4 operator -(const Matrix4x4 &m1, const Matrix4x4 &m2); 17.242 +inline Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2); 17.243 + 17.244 +void operator +=(Matrix4x4 &m1, const Matrix4x4 &m2); 17.245 +void operator -=(Matrix4x4 &m1, const Matrix4x4 &m2); 17.246 +inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2); 17.247 + 17.248 +/* binary operations matrix (op) scalar and scalar (op) matrix */ 17.249 +Matrix4x4 operator *(const Matrix4x4 &mat, scalar_t scalar); 17.250 +Matrix4x4 operator *(scalar_t scalar, const Matrix4x4 &mat); 17.251 + 17.252 +void operator *=(Matrix4x4 &mat, scalar_t scalar); 17.253 + 17.254 +#endif /* __cplusplus */ 17.255 + 17.256 +#include "matrix.inl" 17.257 + 17.258 +#endif /* VMATH_MATRIX_H_ */
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/libs/vmath/matrix.inl Sun May 31 00:40:26 2015 +0300 18.3 @@ -0,0 +1,200 @@ 18.4 +/* 18.5 +libvmath - a vector math library 18.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 18.7 + 18.8 +This program is free software: you can redistribute it and/or modify 18.9 +it under the terms of the GNU Lesser General Public License as published 18.10 +by the Free Software Foundation, either version 3 of the License, or 18.11 +(at your option) any later version. 18.12 + 18.13 +This program is distributed in the hope that it will be useful, 18.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 18.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18.16 +GNU Lesser General Public License for more details. 18.17 + 18.18 +You should have received a copy of the GNU Lesser General Public License 18.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 18.20 +*/ 18.21 + 18.22 +#include <string.h> 18.23 + 18.24 +#ifdef __cplusplus 18.25 +extern "C" { 18.26 +#endif /* __cplusplus */ 18.27 + 18.28 +/* C matrix 3x3 functions */ 18.29 +static inline void m3_identity(mat3_t m) 18.30 +{ 18.31 + static const mat3_t id = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; 18.32 + memcpy(m, id, sizeof id); 18.33 +} 18.34 + 18.35 +static inline void m3_cons(mat3_t m, 18.36 + scalar_t m11, scalar_t m12, scalar_t m13, 18.37 + scalar_t m21, scalar_t m22, scalar_t m23, 18.38 + scalar_t m31, scalar_t m32, scalar_t m33) 18.39 +{ 18.40 + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; 18.41 + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; 18.42 + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; 18.43 +} 18.44 + 18.45 +static inline void m3_copy(mat3_t dest, mat3_t src) 18.46 +{ 18.47 + memcpy(dest, src, sizeof(mat3_t)); 18.48 +} 18.49 + 18.50 + 18.51 +/* C matrix 4x4 functions */ 18.52 +static inline void m4_identity(mat4_t m) 18.53 +{ 18.54 + static const mat4_t id = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; 18.55 + memcpy(m, id, sizeof id); 18.56 +} 18.57 + 18.58 +static inline void m4_cons(mat4_t m, 18.59 + scalar_t m11, scalar_t m12, scalar_t m13, scalar_t m14, 18.60 + scalar_t m21, scalar_t m22, scalar_t m23, scalar_t m24, 18.61 + scalar_t m31, scalar_t m32, scalar_t m33, scalar_t m34, 18.62 + scalar_t m41, scalar_t m42, scalar_t m43, scalar_t m44) 18.63 +{ 18.64 + m[0][0] = m11; m[0][1] = m12; m[0][2] = m13; m[0][3] = m14; 18.65 + m[1][0] = m21; m[1][1] = m22; m[1][2] = m23; m[1][3] = m24; 18.66 + m[2][0] = m31; m[2][1] = m32; m[2][2] = m33; m[2][3] = m34; 18.67 + m[3][0] = m41; m[3][1] = m42; m[3][2] = m43; m[3][3] = m44; 18.68 +} 18.69 + 18.70 +static inline void m4_copy(mat4_t dest, mat4_t src) 18.71 +{ 18.72 + memcpy(dest, src, sizeof(mat4_t)); 18.73 +} 18.74 + 18.75 +static inline void m4_mult(mat4_t res, mat4_t m1, mat4_t m2) 18.76 +{ 18.77 + mat4_t tmp; 18.78 + 18.79 + /* 18.80 + int i, j; 18.81 + for(i=0; i<4; i++) { 18.82 + for(j=0; j<4; j++) { 18.83 + tmp[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] + m1[i][2] * m2[2][j] + m1[i][3] * m2[3][j]; 18.84 + } 18.85 + } 18.86 + */ 18.87 + 18.88 + tmp[0][0] = m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0] + m1[0][2] * m2[2][0] + m1[0][3] * m2[3][0]; 18.89 + tmp[0][1] = m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1] + m1[0][2] * m2[2][1] + m1[0][3] * m2[3][1]; 18.90 + tmp[0][2] = m1[0][0] * m2[0][2] + m1[0][1] * m2[1][2] + m1[0][2] * m2[2][2] + m1[0][3] * m2[3][2]; 18.91 + tmp[0][3] = m1[0][0] * m2[0][3] + m1[0][1] * m2[1][3] + m1[0][2] * m2[2][3] + m1[0][3] * m2[3][3]; 18.92 + 18.93 + tmp[1][0] = m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0] + m1[1][2] * m2[2][0] + m1[1][3] * m2[3][0]; 18.94 + tmp[1][1] = m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1] + m1[1][2] * m2[2][1] + m1[1][3] * m2[3][1]; 18.95 + tmp[1][2] = m1[1][0] * m2[0][2] + m1[1][1] * m2[1][2] + m1[1][2] * m2[2][2] + m1[1][3] * m2[3][2]; 18.96 + tmp[1][3] = m1[1][0] * m2[0][3] + m1[1][1] * m2[1][3] + m1[1][2] * m2[2][3] + m1[1][3] * m2[3][3]; 18.97 + 18.98 + tmp[2][0] = m1[2][0] * m2[0][0] + m1[2][1] * m2[1][0] + m1[2][2] * m2[2][0] + m1[2][3] * m2[3][0]; 18.99 + tmp[2][1] = m1[2][0] * m2[0][1] + m1[2][1] * m2[1][1] + m1[2][2] * m2[2][1] + m1[2][3] * m2[3][1]; 18.100 + tmp[2][2] = m1[2][0] * m2[0][2] + m1[2][1] * m2[1][2] + m1[2][2] * m2[2][2] + m1[2][3] * m2[3][2]; 18.101 + tmp[2][3] = m1[2][0] * m2[0][3] + m1[2][1] * m2[1][3] + m1[2][2] * m2[2][3] + m1[2][3] * m2[3][3]; 18.102 + 18.103 + tmp[3][0] = m1[3][0] * m2[0][0] + m1[3][1] * m2[1][0] + m1[3][2] * m2[2][0] + m1[3][3] * m2[3][0]; 18.104 + tmp[3][1] = m1[3][0] * m2[0][1] + m1[3][1] * m2[1][1] + m1[3][2] * m2[2][1] + m1[3][3] * m2[3][1]; 18.105 + tmp[3][2] = m1[3][0] * m2[0][2] + m1[3][1] * m2[1][2] + m1[3][2] * m2[2][2] + m1[3][3] * m2[3][2]; 18.106 + tmp[3][3] = m1[3][0] * m2[0][3] + m1[3][1] * m2[1][3] + m1[3][2] * m2[2][3] + m1[3][3] * m2[3][3]; 18.107 + 18.108 + m4_copy(res, tmp); 18.109 +} 18.110 + 18.111 +static inline void m4_set_column(mat4_t m, vec4_t v, int idx) 18.112 +{ 18.113 + m[0][idx] = v.x; 18.114 + m[1][idx] = v.y; 18.115 + m[2][idx] = v.z; 18.116 + m[3][idx] = v.w; 18.117 +} 18.118 + 18.119 +static inline void m4_set_row(mat4_t m, vec4_t v, int idx) 18.120 +{ 18.121 + m[idx][0] = v.x; 18.122 + m[idx][1] = v.y; 18.123 + m[idx][2] = v.z; 18.124 + m[idx][3] = v.w; 18.125 +} 18.126 + 18.127 +#ifdef __cplusplus 18.128 +} /* extern "C" */ 18.129 + 18.130 + 18.131 +/* unrolled to hell and inline */ 18.132 +inline Matrix4x4 operator *(const Matrix4x4 &m1, const Matrix4x4 &m2) 18.133 +{ 18.134 + Matrix4x4 res; 18.135 + 18.136 + /* 18.137 + for(i=0; i<4; i++) { 18.138 + for(j=0; j<4; j++) { 18.139 + res.m[i][j] = m1.m[i][0] * m2.m[0][j] + m1.m[i][1] * m2.m[1][j] + m1.m[i][2] * m2.m[2][j] + m1.m[i][3] * m2.m[3][j]; 18.140 + } 18.141 + } 18.142 + */ 18.143 + 18.144 + res.m[0][0] = m1.m[0][0] * m2.m[0][0] + m1.m[0][1] * m2.m[1][0] + m1.m[0][2] * m2.m[2][0] + m1.m[0][3] * m2.m[3][0]; 18.145 + res.m[0][1] = m1.m[0][0] * m2.m[0][1] + m1.m[0][1] * m2.m[1][1] + m1.m[0][2] * m2.m[2][1] + m1.m[0][3] * m2.m[3][1]; 18.146 + res.m[0][2] = m1.m[0][0] * m2.m[0][2] + m1.m[0][1] * m2.m[1][2] + m1.m[0][2] * m2.m[2][2] + m1.m[0][3] * m2.m[3][2]; 18.147 + res.m[0][3] = m1.m[0][0] * m2.m[0][3] + m1.m[0][1] * m2.m[1][3] + m1.m[0][2] * m2.m[2][3] + m1.m[0][3] * m2.m[3][3]; 18.148 + 18.149 + res.m[1][0] = m1.m[1][0] * m2.m[0][0] + m1.m[1][1] * m2.m[1][0] + m1.m[1][2] * m2.m[2][0] + m1.m[1][3] * m2.m[3][0]; 18.150 + res.m[1][1] = m1.m[1][0] * m2.m[0][1] + m1.m[1][1] * m2.m[1][1] + m1.m[1][2] * m2.m[2][1] + m1.m[1][3] * m2.m[3][1]; 18.151 + res.m[1][2] = m1.m[1][0] * m2.m[0][2] + m1.m[1][1] * m2.m[1][2] + m1.m[1][2] * m2.m[2][2] + m1.m[1][3] * m2.m[3][2]; 18.152 + res.m[1][3] = m1.m[1][0] * m2.m[0][3] + m1.m[1][1] * m2.m[1][3] + m1.m[1][2] * m2.m[2][3] + m1.m[1][3] * m2.m[3][3]; 18.153 + 18.154 + res.m[2][0] = m1.m[2][0] * m2.m[0][0] + m1.m[2][1] * m2.m[1][0] + m1.m[2][2] * m2.m[2][0] + m1.m[2][3] * m2.m[3][0]; 18.155 + res.m[2][1] = m1.m[2][0] * m2.m[0][1] + m1.m[2][1] * m2.m[1][1] + m1.m[2][2] * m2.m[2][1] + m1.m[2][3] * m2.m[3][1]; 18.156 + res.m[2][2] = m1.m[2][0] * m2.m[0][2] + m1.m[2][1] * m2.m[1][2] + m1.m[2][2] * m2.m[2][2] + m1.m[2][3] * m2.m[3][2]; 18.157 + res.m[2][3] = m1.m[2][0] * m2.m[0][3] + m1.m[2][1] * m2.m[1][3] + m1.m[2][2] * m2.m[2][3] + m1.m[2][3] * m2.m[3][3]; 18.158 + 18.159 + res.m[3][0] = m1.m[3][0] * m2.m[0][0] + m1.m[3][1] * m2.m[1][0] + m1.m[3][2] * m2.m[2][0] + m1.m[3][3] * m2.m[3][0]; 18.160 + res.m[3][1] = m1.m[3][0] * m2.m[0][1] + m1.m[3][1] * m2.m[1][1] + m1.m[3][2] * m2.m[2][1] + m1.m[3][3] * m2.m[3][1]; 18.161 + res.m[3][2] = m1.m[3][0] * m2.m[0][2] + m1.m[3][1] * m2.m[1][2] + m1.m[3][2] * m2.m[2][2] + m1.m[3][3] * m2.m[3][2]; 18.162 + res.m[3][3] = m1.m[3][0] * m2.m[0][3] + m1.m[3][1] * m2.m[1][3] + m1.m[3][2] * m2.m[2][3] + m1.m[3][3] * m2.m[3][3]; 18.163 + 18.164 + return res; 18.165 +} 18.166 + 18.167 +inline void operator *=(Matrix4x4 &m1, const Matrix4x4 &m2) 18.168 +{ 18.169 + Matrix4x4 res = m1 * m2; 18.170 + m1 = res; 18.171 +} 18.172 + 18.173 + 18.174 +inline scalar_t *Matrix3x3::operator [](int index) 18.175 +{ 18.176 + return m[index]; 18.177 +} 18.178 + 18.179 +inline const scalar_t *Matrix3x3::operator [](int index) const 18.180 +{ 18.181 + return m[index]; 18.182 +} 18.183 + 18.184 +inline void Matrix3x3::reset_identity() 18.185 +{ 18.186 + *this = identity; 18.187 +} 18.188 + 18.189 +inline scalar_t *Matrix4x4::operator [](int index) 18.190 +{ 18.191 + return m[index]; 18.192 +} 18.193 + 18.194 +inline const scalar_t *Matrix4x4::operator [](int index) const 18.195 +{ 18.196 + return m[index]; 18.197 +} 18.198 + 18.199 +inline void Matrix4x4::reset_identity() 18.200 +{ 18.201 + *this = identity; 18.202 +} 18.203 +#endif /* __cplusplus */
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/libs/vmath/matrix_c.c Sun May 31 00:40:26 2015 +0300 19.3 @@ -0,0 +1,292 @@ 19.4 +/* 19.5 +libvmath - a vector math library 19.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 19.7 + 19.8 +This program is free software: you can redistribute it and/or modify 19.9 +it under the terms of the GNU Lesser General Public License as published 19.10 +by the Free Software Foundation, either version 3 of the License, or 19.11 +(at your option) any later version. 19.12 + 19.13 +This program is distributed in the hope that it will be useful, 19.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 19.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19.16 +GNU Lesser General Public License for more details. 19.17 + 19.18 +You should have received a copy of the GNU Lesser General Public License 19.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 19.20 +*/ 19.21 + 19.22 + 19.23 +#include <stdio.h> 19.24 +#include "matrix.h" 19.25 +#include "vector.h" 19.26 +#include "quat.h" 19.27 + 19.28 +void m3_to_m4(mat4_t dest, mat3_t src) 19.29 +{ 19.30 + int i, j; 19.31 + 19.32 + memset(dest, 0, sizeof(mat4_t)); 19.33 + for(i=0; i<3; i++) { 19.34 + for(j=0; j<3; j++) { 19.35 + dest[i][j] = src[i][j]; 19.36 + } 19.37 + } 19.38 + dest[3][3] = 1.0; 19.39 +} 19.40 + 19.41 +void m3_print(FILE *fp, mat3_t m) 19.42 +{ 19.43 + int i; 19.44 + for(i=0; i<3; i++) { 19.45 + fprintf(fp, "[ %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2]); 19.46 + } 19.47 +} 19.48 + 19.49 +/* C matrix 4x4 functions */ 19.50 +void m4_to_m3(mat3_t dest, mat4_t src) 19.51 +{ 19.52 + int i, j; 19.53 + for(i=0; i<3; i++) { 19.54 + for(j=0; j<3; j++) { 19.55 + dest[i][j] = src[i][j]; 19.56 + } 19.57 + } 19.58 +} 19.59 + 19.60 +void m4_set_translation(mat4_t m, scalar_t x, scalar_t y, scalar_t z) 19.61 +{ 19.62 + m4_identity(m); 19.63 + m[0][3] = x; 19.64 + m[1][3] = y; 19.65 + m[2][3] = z; 19.66 +} 19.67 + 19.68 +void m4_translate(mat4_t m, scalar_t x, scalar_t y, scalar_t z) 19.69 +{ 19.70 + mat4_t tm; 19.71 + m4_set_translation(tm, x, y, z); 19.72 + m4_mult(m, m, tm); 19.73 +} 19.74 + 19.75 +void m4_rotate(mat4_t m, scalar_t x, scalar_t y, scalar_t z) 19.76 +{ 19.77 + m4_rotate_x(m, x); 19.78 + m4_rotate_y(m, y); 19.79 + m4_rotate_z(m, z); 19.80 +} 19.81 + 19.82 +void m4_set_rotation_x(mat4_t m, scalar_t angle) 19.83 +{ 19.84 + m4_identity(m); 19.85 + m[1][1] = cos(angle); m[1][2] = -sin(angle); 19.86 + m[2][1] = sin(angle); m[2][2] = cos(angle); 19.87 +} 19.88 + 19.89 +void m4_rotate_x(mat4_t m, scalar_t angle) 19.90 +{ 19.91 + mat4_t rm; 19.92 + m4_set_rotation_x(rm, angle); 19.93 + m4_mult(m, m, rm); 19.94 +} 19.95 + 19.96 +void m4_set_rotation_y(mat4_t m, scalar_t angle) 19.97 +{ 19.98 + m4_identity(m); 19.99 + m[0][0] = cos(angle); m[0][2] = sin(angle); 19.100 + m[2][0] = -sin(angle); m[2][2] = cos(angle); 19.101 +} 19.102 + 19.103 +void m4_rotate_y(mat4_t m, scalar_t angle) 19.104 +{ 19.105 + mat4_t rm; 19.106 + m4_set_rotation_y(rm, angle); 19.107 + m4_mult(m, m, rm); 19.108 +} 19.109 + 19.110 +void m4_set_rotation_z(mat4_t m, scalar_t angle) 19.111 +{ 19.112 + m4_identity(m); 19.113 + m[0][0] = cos(angle); m[0][1] = -sin(angle); 19.114 + m[1][0] = sin(angle); m[1][1] = cos(angle); 19.115 +} 19.116 + 19.117 +void m4_rotate_z(mat4_t m, scalar_t angle) 19.118 +{ 19.119 + mat4_t rm; 19.120 + m4_set_rotation_z(rm, angle); 19.121 + m4_mult(m, m, rm); 19.122 +} 19.123 + 19.124 +void m4_set_rotation_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) 19.125 +{ 19.126 + scalar_t sina = sin(angle); 19.127 + scalar_t cosa = cos(angle); 19.128 + scalar_t one_minus_cosa = 1.0 - cosa; 19.129 + scalar_t nxsq = x * x; 19.130 + scalar_t nysq = y * y; 19.131 + scalar_t nzsq = z * z; 19.132 + 19.133 + m[0][0] = nxsq + (1.0 - nxsq) * cosa; 19.134 + m[0][1] = x * y * one_minus_cosa - z * sina; 19.135 + m[0][2] = x * z * one_minus_cosa + y * sina; 19.136 + m[1][0] = x * y * one_minus_cosa + z * sina; 19.137 + m[1][1] = nysq + (1.0 - nysq) * cosa; 19.138 + m[1][2] = y * z * one_minus_cosa - x * sina; 19.139 + m[2][0] = x * z * one_minus_cosa - y * sina; 19.140 + m[2][1] = y * z * one_minus_cosa + x * sina; 19.141 + m[2][2] = nzsq + (1.0 - nzsq) * cosa; 19.142 + 19.143 + /* the rest are identity */ 19.144 + m[3][0] = m[3][1] = m[3][2] = m[0][3] = m[1][3] = m[2][3] = 0.0; 19.145 + m[3][3] = 1.0; 19.146 +} 19.147 + 19.148 +void m4_rotate_axis(mat4_t m, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) 19.149 +{ 19.150 + mat4_t xform; 19.151 + m4_set_rotation_axis(xform, angle, x, y, z); 19.152 + m4_mult(m, m, xform); 19.153 +} 19.154 + 19.155 +void m4_rotate_quat(mat4_t m, quat_t q) 19.156 +{ 19.157 + mat4_t rm; 19.158 + quat_to_mat4(rm, q); 19.159 + m4_mult(m, m, rm); 19.160 +} 19.161 + 19.162 +void m4_scale(mat4_t m, scalar_t x, scalar_t y, scalar_t z) 19.163 +{ 19.164 + mat4_t sm; 19.165 + m4_identity(sm); 19.166 + sm[0][0] = x; 19.167 + sm[1][1] = y; 19.168 + sm[2][2] = z; 19.169 + m4_mult(m, m, sm); 19.170 +} 19.171 + 19.172 +void m4_transpose(mat4_t res, mat4_t m) 19.173 +{ 19.174 + int i, j; 19.175 + mat4_t tmp; 19.176 + m4_copy(tmp, m); 19.177 + 19.178 + for(i=0; i<4; i++) { 19.179 + for(j=0; j<4; j++) { 19.180 + res[i][j] = tmp[j][i]; 19.181 + } 19.182 + } 19.183 +} 19.184 + 19.185 +scalar_t m4_determinant(mat4_t m) 19.186 +{ 19.187 + scalar_t det11 = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 19.188 + (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 19.189 + (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 19.190 + 19.191 + scalar_t det12 = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 19.192 + (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 19.193 + (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 19.194 + 19.195 + scalar_t det13 = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 19.196 + (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 19.197 + (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 19.198 + 19.199 + scalar_t det14 = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 19.200 + (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 19.201 + (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 19.202 + 19.203 + return m[0][0] * det11 - m[0][1] * det12 + m[0][2] * det13 - m[0][3] * det14; 19.204 +} 19.205 + 19.206 +void m4_adjoint(mat4_t res, mat4_t m) 19.207 +{ 19.208 + int i, j; 19.209 + mat4_t coef; 19.210 + 19.211 + coef[0][0] = (m[1][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 19.212 + (m[1][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 19.213 + (m[1][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 19.214 + coef[0][1] = (m[1][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 19.215 + (m[1][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 19.216 + (m[1][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 19.217 + coef[0][2] = (m[1][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 19.218 + (m[1][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 19.219 + (m[1][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 19.220 + coef[0][3] = (m[1][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 19.221 + (m[1][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 19.222 + (m[1][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 19.223 + 19.224 + coef[1][0] = (m[0][1] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 19.225 + (m[0][2] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) + 19.226 + (m[0][3] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])); 19.227 + coef[1][1] = (m[0][0] * (m[2][2] * m[3][3] - m[3][2] * m[2][3])) - 19.228 + (m[0][2] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 19.229 + (m[0][3] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])); 19.230 + coef[1][2] = (m[0][0] * (m[2][1] * m[3][3] - m[3][1] * m[2][3])) - 19.231 + (m[0][1] * (m[2][0] * m[3][3] - m[3][0] * m[2][3])) + 19.232 + (m[0][3] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 19.233 + coef[1][3] = (m[0][0] * (m[2][1] * m[3][2] - m[3][1] * m[2][2])) - 19.234 + (m[0][1] * (m[2][0] * m[3][2] - m[3][0] * m[2][2])) + 19.235 + (m[0][2] * (m[2][0] * m[3][1] - m[3][0] * m[2][1])); 19.236 + 19.237 + coef[2][0] = (m[0][1] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - 19.238 + (m[0][2] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) + 19.239 + (m[0][3] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])); 19.240 + coef[2][1] = (m[0][0] * (m[1][2] * m[3][3] - m[3][2] * m[1][3])) - 19.241 + (m[0][2] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + 19.242 + (m[0][3] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])); 19.243 + coef[2][2] = (m[0][0] * (m[1][1] * m[3][3] - m[3][1] * m[1][3])) - 19.244 + (m[0][1] * (m[1][0] * m[3][3] - m[3][0] * m[1][3])) + 19.245 + (m[0][3] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); 19.246 + coef[2][3] = (m[0][0] * (m[1][1] * m[3][2] - m[3][1] * m[1][2])) - 19.247 + (m[0][1] * (m[1][0] * m[3][2] - m[3][0] * m[1][2])) + 19.248 + (m[0][2] * (m[1][0] * m[3][1] - m[3][0] * m[1][1])); 19.249 + 19.250 + coef[3][0] = (m[0][1] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - 19.251 + (m[0][2] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) + 19.252 + (m[0][3] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])); 19.253 + coef[3][1] = (m[0][0] * (m[1][2] * m[2][3] - m[2][2] * m[1][3])) - 19.254 + (m[0][2] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + 19.255 + (m[0][3] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])); 19.256 + coef[3][2] = (m[0][0] * (m[1][1] * m[2][3] - m[2][1] * m[1][3])) - 19.257 + (m[0][1] * (m[1][0] * m[2][3] - m[2][0] * m[1][3])) + 19.258 + (m[0][3] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); 19.259 + coef[3][3] = (m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])) - 19.260 + (m[0][1] * (m[1][0] * m[2][2] - m[2][0] * m[1][2])) + 19.261 + (m[0][2] * (m[1][0] * m[2][1] - m[2][0] * m[1][1])); 19.262 + 19.263 + m4_transpose(res, coef); 19.264 + 19.265 + for(i=0; i<4; i++) { 19.266 + for(j=0; j<4; j++) { 19.267 + res[i][j] = j % 2 ? -res[i][j] : res[i][j]; 19.268 + if(i % 2) res[i][j] = -res[i][j]; 19.269 + } 19.270 + } 19.271 +} 19.272 + 19.273 +void m4_inverse(mat4_t res, mat4_t m) 19.274 +{ 19.275 + int i, j; 19.276 + mat4_t adj; 19.277 + scalar_t det; 19.278 + 19.279 + m4_adjoint(adj, m); 19.280 + det = m4_determinant(m); 19.281 + 19.282 + for(i=0; i<4; i++) { 19.283 + for(j=0; j<4; j++) { 19.284 + res[i][j] = adj[i][j] / det; 19.285 + } 19.286 + } 19.287 +} 19.288 + 19.289 +void m4_print(FILE *fp, mat4_t m) 19.290 +{ 19.291 + int i; 19.292 + for(i=0; i<4; i++) { 19.293 + fprintf(fp, "[ %12.5f %12.5f %12.5f %12.5f ]\n", (float)m[i][0], (float)m[i][1], (float)m[i][2], (float)m[i][3]); 19.294 + } 19.295 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/libs/vmath/quat.cc Sun May 31 00:40:26 2015 +0300 20.3 @@ -0,0 +1,229 @@ 20.4 +/* 20.5 +libvmath - a vector math library 20.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 20.7 + 20.8 +This program is free software: you can redistribute it and/or modify 20.9 +it under the terms of the GNU Lesser General Public License as published 20.10 +by the Free Software Foundation, either version 3 of the License, or 20.11 +(at your option) any later version. 20.12 + 20.13 +This program is distributed in the hope that it will be useful, 20.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 20.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20.16 +GNU Lesser General Public License for more details. 20.17 + 20.18 +You should have received a copy of the GNU Lesser General Public License 20.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 20.20 +*/ 20.21 +#include "quat.h" 20.22 +#include "vmath.h" 20.23 + 20.24 +Quaternion::Quaternion() 20.25 +{ 20.26 + s = 1.0; 20.27 + v.x = v.y = v.z = 0.0; 20.28 +} 20.29 + 20.30 +Quaternion::Quaternion(scalar_t s, const Vector3 &v) 20.31 +{ 20.32 + this->s = s; 20.33 + this->v = v; 20.34 +} 20.35 + 20.36 +Quaternion::Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z) 20.37 +{ 20.38 + v.x = x; 20.39 + v.y = y; 20.40 + v.z = z; 20.41 + this->s = s; 20.42 +} 20.43 + 20.44 +Quaternion::Quaternion(const Vector3 &axis, scalar_t angle) 20.45 +{ 20.46 + set_rotation(axis, angle); 20.47 +} 20.48 + 20.49 +Quaternion::Quaternion(const quat_t &quat) 20.50 +{ 20.51 + v.x = quat.x; 20.52 + v.y = quat.y; 20.53 + v.z = quat.z; 20.54 + s = quat.w; 20.55 +} 20.56 + 20.57 +Quaternion Quaternion::operator +(const Quaternion &quat) const 20.58 +{ 20.59 + return Quaternion(s + quat.s, v + quat.v); 20.60 +} 20.61 + 20.62 +Quaternion Quaternion::operator -(const Quaternion &quat) const 20.63 +{ 20.64 + return Quaternion(s - quat.s, v - quat.v); 20.65 +} 20.66 + 20.67 +Quaternion Quaternion::operator -() const 20.68 +{ 20.69 + return Quaternion(-s, -v); 20.70 +} 20.71 + 20.72 +/** Quaternion Multiplication: 20.73 + * Q1*Q2 = [s1*s2 - v1.v2, s1*v2 + s2*v1 + v1(x)v2] 20.74 + */ 20.75 +Quaternion Quaternion::operator *(const Quaternion &quat) const 20.76 +{ 20.77 + Quaternion newq; 20.78 + newq.s = s * quat.s - dot_product(v, quat.v); 20.79 + newq.v = quat.v * s + v * quat.s + cross_product(v, quat.v); 20.80 + return newq; 20.81 +} 20.82 + 20.83 +void Quaternion::operator +=(const Quaternion &quat) 20.84 +{ 20.85 + *this = Quaternion(s + quat.s, v + quat.v); 20.86 +} 20.87 + 20.88 +void Quaternion::operator -=(const Quaternion &quat) 20.89 +{ 20.90 + *this = Quaternion(s - quat.s, v - quat.v); 20.91 +} 20.92 + 20.93 +void Quaternion::operator *=(const Quaternion &quat) 20.94 +{ 20.95 + *this = *this * quat; 20.96 +} 20.97 + 20.98 +void Quaternion::reset_identity() 20.99 +{ 20.100 + s = 1.0; 20.101 + v.x = v.y = v.z = 0.0; 20.102 +} 20.103 + 20.104 +Quaternion Quaternion::conjugate() const 20.105 +{ 20.106 + return Quaternion(s, -v); 20.107 +} 20.108 + 20.109 +scalar_t Quaternion::length() const 20.110 +{ 20.111 + return (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); 20.112 +} 20.113 + 20.114 +/** Q * ~Q = ||Q||^2 */ 20.115 +scalar_t Quaternion::length_sq() const 20.116 +{ 20.117 + return v.x*v.x + v.y*v.y + v.z*v.z + s*s; 20.118 +} 20.119 + 20.120 +void Quaternion::normalize() 20.121 +{ 20.122 + scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); 20.123 + v.x /= len; 20.124 + v.y /= len; 20.125 + v.z /= len; 20.126 + s /= len; 20.127 +} 20.128 + 20.129 +Quaternion Quaternion::normalized() const 20.130 +{ 20.131 + Quaternion nq = *this; 20.132 + scalar_t len = (scalar_t)sqrt(v.x*v.x + v.y*v.y + v.z*v.z + s*s); 20.133 + nq.v.x /= len; 20.134 + nq.v.y /= len; 20.135 + nq.v.z /= len; 20.136 + nq.s /= len; 20.137 + return nq; 20.138 +} 20.139 + 20.140 +/** Quaternion Inversion: Q^-1 = ~Q / ||Q||^2 */ 20.141 +Quaternion Quaternion::inverse() const 20.142 +{ 20.143 + Quaternion inv = conjugate(); 20.144 + scalar_t lensq = length_sq(); 20.145 + inv.v /= lensq; 20.146 + inv.s /= lensq; 20.147 + 20.148 + return inv; 20.149 +} 20.150 + 20.151 + 20.152 +void Quaternion::set_rotation(const Vector3 &axis, scalar_t angle) 20.153 +{ 20.154 + scalar_t half_angle = angle / 2.0; 20.155 + s = cos(half_angle); 20.156 + v = axis * sin(half_angle); 20.157 +} 20.158 + 20.159 +void Quaternion::rotate(const Vector3 &axis, scalar_t angle) 20.160 +{ 20.161 + Quaternion q; 20.162 + scalar_t half_angle = angle / 2.0; 20.163 + q.s = cos(half_angle); 20.164 + q.v = axis * sin(half_angle); 20.165 + 20.166 + *this *= q; 20.167 +} 20.168 + 20.169 +void Quaternion::rotate(const Quaternion &q) 20.170 +{ 20.171 + *this = q * *this * q.conjugate(); 20.172 +} 20.173 + 20.174 +Matrix3x3 Quaternion::get_rotation_matrix() const 20.175 +{ 20.176 + return Matrix3x3( 20.177 + 1.0 - 2.0 * v.y*v.y - 2.0 * v.z*v.z, 2.0 * v.x * v.y - 2.0 * s * v.z, 2.0 * v.z * v.x + 2.0 * s * v.y, 20.178 + 2.0 * v.x * v.y + 2.0 * s * v.z, 1.0 - 2.0 * v.x*v.x - 2.0 * v.z*v.z, 2.0 * v.y * v.z - 2.0 * s * v.x, 20.179 + 2.0 * v.z * v.x - 2.0 * s * v.y, 2.0 * v.y * v.z + 2.0 * s * v.x, 1.0 - 2.0 * v.x*v.x - 2.0 * v.y*v.y); 20.180 +} 20.181 + 20.182 + 20.183 +/** Spherical linear interpolation (slerp) */ 20.184 +Quaternion slerp(const Quaternion &quat1, const Quaternion &q2, scalar_t t) 20.185 +{ 20.186 + Quaternion q1 = quat1; 20.187 + scalar_t dot = q1.s * q2.s + q1.v.x * q2.v.x + q1.v.y * q2.v.y + q1.v.z * q2.v.z; 20.188 + 20.189 + if(dot < 0.0) { 20.190 + /* make sure we interpolate across the shortest arc */ 20.191 + q1 = -quat1; 20.192 + dot = -dot; 20.193 + } 20.194 + 20.195 + /* clamp dot to [-1, 1] in order to avoid domain errors in acos due to 20.196 + * floating point imprecisions 20.197 + */ 20.198 + if(dot < -1.0) dot = -1.0; 20.199 + if(dot > 1.0) dot = 1.0; 20.200 + 20.201 + scalar_t angle = acos(dot); 20.202 + scalar_t a, b; 20.203 + 20.204 + scalar_t sin_angle = sin(angle); 20.205 + if(fabs(sin_angle) < SMALL_NUMBER) { 20.206 + /* for very small angles or completely opposite orientations 20.207 + * use linear interpolation to avoid div/zero (in the first case it makes sense, 20.208 + * the second case is pretty much undefined anyway I guess ... 20.209 + */ 20.210 + a = 1.0f - t; 20.211 + b = t; 20.212 + } else { 20.213 + a = sin((1.0f - t) * angle) / sin_angle; 20.214 + b = sin(t * angle) / sin_angle; 20.215 + } 20.216 + 20.217 + scalar_t x = q1.v.x * a + q2.v.x * b; 20.218 + scalar_t y = q1.v.y * a + q2.v.y * b; 20.219 + scalar_t z = q1.v.z * a + q2.v.z * b; 20.220 + scalar_t s = q1.s * a + q2.s * b; 20.221 + 20.222 + return Quaternion(s, Vector3(x, y, z)); 20.223 +} 20.224 + 20.225 + 20.226 +/* 20.227 +std::ostream &operator <<(std::ostream &out, const Quaternion &q) 20.228 +{ 20.229 + out << "(" << q.s << ", " << q.v << ")"; 20.230 + return out; 20.231 +} 20.232 +*/
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/libs/vmath/quat.h Sun May 31 00:40:26 2015 +0300 21.3 @@ -0,0 +1,114 @@ 21.4 +/* 21.5 +libvmath - a vector math library 21.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 21.7 + 21.8 +This program is free software: you can redistribute it and/or modify 21.9 +it under the terms of the GNU Lesser General Public License as published 21.10 +by the Free Software Foundation, either version 3 of the License, or 21.11 +(at your option) any later version. 21.12 + 21.13 +This program is distributed in the hope that it will be useful, 21.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 21.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21.16 +GNU Lesser General Public License for more details. 21.17 + 21.18 +You should have received a copy of the GNU Lesser General Public License 21.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 21.20 +*/ 21.21 + 21.22 +#ifndef VMATH_QUATERNION_H_ 21.23 +#define VMATH_QUATERNION_H_ 21.24 + 21.25 +#include <stdio.h> 21.26 +#include "vmath_types.h" 21.27 +#include "vector.h" 21.28 + 21.29 +#ifdef __cplusplus 21.30 +extern "C" { 21.31 +#endif /* __cplusplus */ 21.32 + 21.33 +#define quat_cons(s, x, y, z) v4_cons(x, y, z, s) 21.34 +#define quat_vec(q) v3_cons((q).x, (q).y, (q).z) 21.35 +#define quat_s(q) ((q).w) 21.36 +#define quat_identity() quat_cons(1.0, 0.0, 0.0, 0.0) 21.37 +void quat_print(FILE *fp, quat_t q); 21.38 + 21.39 +#define quat_add v4_add 21.40 +#define quat_sub v4_sub 21.41 +#define quat_neg v4_neg 21.42 + 21.43 +static inline quat_t quat_mul(quat_t q1, quat_t q2); 21.44 + 21.45 +static inline quat_t quat_conjugate(quat_t q); 21.46 + 21.47 +#define quat_length v4_length 21.48 +#define quat_length_sq v4_length_sq 21.49 + 21.50 +#define quat_normalize v4_normalize 21.51 +static inline quat_t quat_inverse(quat_t q); 21.52 + 21.53 +quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); 21.54 +quat_t quat_rotate_quat(quat_t q, quat_t rotq); 21.55 + 21.56 +static inline void quat_to_mat3(mat3_t res, quat_t q); 21.57 +static inline void quat_to_mat4(mat4_t res, quat_t q); 21.58 + 21.59 +#define quat_lerp quat_slerp 21.60 +quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t); 21.61 + 21.62 + 21.63 +#ifdef __cplusplus 21.64 +} /* extern "C" */ 21.65 + 21.66 +/* Quaternion */ 21.67 +class Quaternion { 21.68 +public: 21.69 + scalar_t s; 21.70 + Vector3 v; 21.71 + 21.72 + Quaternion(); 21.73 + Quaternion(scalar_t s, const Vector3 &v); 21.74 + Quaternion(scalar_t s, scalar_t x, scalar_t y, scalar_t z); 21.75 + Quaternion(const Vector3 &axis, scalar_t angle); 21.76 + Quaternion(const quat_t &quat); 21.77 + 21.78 + Quaternion operator +(const Quaternion &quat) const; 21.79 + Quaternion operator -(const Quaternion &quat) const; 21.80 + Quaternion operator -() const; 21.81 + Quaternion operator *(const Quaternion &quat) const; 21.82 + 21.83 + void operator +=(const Quaternion &quat); 21.84 + void operator -=(const Quaternion &quat); 21.85 + void operator *=(const Quaternion &quat); 21.86 + 21.87 + void reset_identity(); 21.88 + 21.89 + Quaternion conjugate() const; 21.90 + 21.91 + scalar_t length() const; 21.92 + scalar_t length_sq() const; 21.93 + 21.94 + void normalize(); 21.95 + Quaternion normalized() const; 21.96 + 21.97 + Quaternion inverse() const; 21.98 + 21.99 + void set_rotation(const Vector3 &axis, scalar_t angle); 21.100 + void rotate(const Vector3 &axis, scalar_t angle); 21.101 + /* note: this is a totally different operation from the above 21.102 + * this treats the quaternion as signifying direction and rotates 21.103 + * it by a rotation quaternion by rot * q * rot' 21.104 + */ 21.105 + void rotate(const Quaternion &q); 21.106 + 21.107 + Matrix3x3 get_rotation_matrix() const; 21.108 +}; 21.109 + 21.110 +Quaternion slerp(const Quaternion &q1, const Quaternion &q2, scalar_t t); 21.111 +inline Quaternion lerp(const Quaternion &q1, const Quaternion &q2, scalar_t t); 21.112 + 21.113 +#endif /* __cplusplus */ 21.114 + 21.115 +#include "quat.inl" 21.116 + 21.117 +#endif /* VMATH_QUATERNION_H_ */
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/libs/vmath/quat.inl Sun May 31 00:40:26 2015 +0300 22.3 @@ -0,0 +1,81 @@ 22.4 +/* 22.5 +libvmath - a vector math library 22.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 22.7 + 22.8 +This program is free software: you can redistribute it and/or modify 22.9 +it under the terms of the GNU Lesser General Public License as published 22.10 +by the Free Software Foundation, either version 3 of the License, or 22.11 +(at your option) any later version. 22.12 + 22.13 +This program is distributed in the hope that it will be useful, 22.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 22.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22.16 +GNU Lesser General Public License for more details. 22.17 + 22.18 +You should have received a copy of the GNU Lesser General Public License 22.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 22.20 +*/ 22.21 + 22.22 +#include "vector.h" 22.23 +#include "matrix.h" 22.24 + 22.25 +#ifdef __cplusplus 22.26 +extern "C" { 22.27 +#endif /* __cplusplus */ 22.28 + 22.29 +static inline quat_t quat_mul(quat_t q1, quat_t q2) 22.30 +{ 22.31 + quat_t res; 22.32 + vec3_t v1 = quat_vec(q1); 22.33 + vec3_t v2 = quat_vec(q2); 22.34 + 22.35 + res.w = q1.w * q2.w - v3_dot(v1, v2); 22.36 + /* resvec = v2 * q1 + v1 * q2 + cross(v1, v2) */ 22.37 + res.x = v2.x * q1.w + v1.x * q2.w + (v1.y * v2.z - v1.z * v2.y); 22.38 + res.y = v2.y * q1.w + v1.y * q2.w + (v1.z * v2.x - v1.x * v2.z); 22.39 + res.z = v2.z * q1.w + v1.z * q2.w + (v1.x * v2.y - v1.y * v2.x); 22.40 + return res; 22.41 +} 22.42 + 22.43 +static inline quat_t quat_conjugate(quat_t q) 22.44 +{ 22.45 + q.x = -q.x; 22.46 + q.y = -q.y; 22.47 + q.z = -q.z; 22.48 + return q; 22.49 +} 22.50 + 22.51 +static inline quat_t quat_inverse(quat_t q) 22.52 +{ 22.53 + scalar_t lensq = quat_length_sq(q); 22.54 + q = quat_conjugate(q); 22.55 + q.x /= lensq; 22.56 + q.y /= lensq; 22.57 + q.z /= lensq; 22.58 + q.w /= lensq; 22.59 + return q; 22.60 +} 22.61 + 22.62 +static inline void quat_to_mat3(mat3_t res, quat_t q) 22.63 +{ 22.64 + m3_cons(res, 1.0 - 2.0 * q.y*q.y - 2.0 * q.z*q.z, 2.0 * q.x * q.y - 2.0 * q.w * q.z, 2.0 * q.z * q.x + 2.0 * q.w * q.y, 22.65 + 2.0 * q.x * q.y + 2.0 * q.w * q.z, 1.0 - 2.0 * q.x*q.x - 2.0 * q.z*q.z, 2.0 * q.y * q.z - 2.0 * q.w * q.x, 22.66 + 2.0 * q.z * q.x - 2.0 * q.w * q.y, 2.0 * q.y * q.z + 2.0 * q.w * q.x, 1.0 - 2.0 * q.x*q.x - 2.0 * q.y*q.y); 22.67 +} 22.68 + 22.69 +static inline void quat_to_mat4(mat4_t res, quat_t q) 22.70 +{ 22.71 + m4_cons(res, 1.0 - 2.0 * q.y*q.y - 2.0 * q.z*q.z, 2.0 * q.x * q.y - 2.0 * q.w * q.z, 2.0 * q.z * q.x + 2.0 * q.w * q.y, 0, 22.72 + 2.0 * q.x * q.y + 2.0 * q.w * q.z, 1.0 - 2.0 * q.x*q.x - 2.0 * q.z*q.z, 2.0 * q.y * q.z - 2.0 * q.w * q.x, 0, 22.73 + 2.0 * q.z * q.x - 2.0 * q.w * q.y, 2.0 * q.y * q.z + 2.0 * q.w * q.x, 1.0 - 2.0 * q.x*q.x - 2.0 * q.y*q.y, 0, 22.74 + 0, 0, 0, 1); 22.75 +} 22.76 + 22.77 +#ifdef __cplusplus 22.78 +} /* extern "C" */ 22.79 + 22.80 +inline Quaternion lerp(const Quaternion &a, const Quaternion &b, scalar_t t) 22.81 +{ 22.82 + return slerp(a, b, t); 22.83 +} 22.84 +#endif /* __cplusplus */
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/libs/vmath/quat_c.c Sun May 31 00:40:26 2015 +0300 23.3 @@ -0,0 +1,89 @@ 23.4 +/* 23.5 +libvmath - a vector math library 23.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 23.7 + 23.8 +This program is free software: you can redistribute it and/or modify 23.9 +it under the terms of the GNU Lesser General Public License as published 23.10 +by the Free Software Foundation, either version 3 of the License, or 23.11 +(at your option) any later version. 23.12 + 23.13 +This program is distributed in the hope that it will be useful, 23.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 23.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23.16 +GNU Lesser General Public License for more details. 23.17 + 23.18 +You should have received a copy of the GNU Lesser General Public License 23.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 23.20 +*/ 23.21 + 23.22 + 23.23 +#include <stdio.h> 23.24 +#include <math.h> 23.25 +#include "quat.h" 23.26 + 23.27 +void quat_print(FILE *fp, quat_t q) 23.28 +{ 23.29 + fprintf(fp, "([ %.4f %.4f %.4f ] %.4f)", q.x, q.y, q.z, q.w); 23.30 +} 23.31 + 23.32 +quat_t quat_rotate(quat_t q, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) 23.33 +{ 23.34 + quat_t rq; 23.35 + scalar_t half_angle = angle * 0.5; 23.36 + scalar_t sin_half = sin(half_angle); 23.37 + 23.38 + rq.w = cos(half_angle); 23.39 + rq.x = x * sin_half; 23.40 + rq.y = y * sin_half; 23.41 + rq.z = z * sin_half; 23.42 + 23.43 + return quat_mul(q, rq); 23.44 +} 23.45 + 23.46 +quat_t quat_rotate_quat(quat_t q, quat_t rotq) 23.47 +{ 23.48 + return quat_mul(quat_mul(rotq, q), quat_conjugate(rotq)); 23.49 +} 23.50 + 23.51 +quat_t quat_slerp(quat_t q1, quat_t q2, scalar_t t) 23.52 +{ 23.53 + quat_t res; 23.54 + scalar_t a, b, angle, sin_angle, dot; 23.55 + 23.56 + dot = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z; 23.57 + if(dot < 0.0) { 23.58 + /* make sure we interpolate across the shortest arc */ 23.59 + q1.x = -q1.x; 23.60 + q1.y = -q1.y; 23.61 + q1.z = -q1.z; 23.62 + q1.w = -q1.w; 23.63 + dot = -dot; 23.64 + } 23.65 + 23.66 + /* clamp dot to [-1, 1] in order to avoid domain errors in acos due to 23.67 + * floating point imprecisions 23.68 + */ 23.69 + if(dot < -1.0) dot = -1.0; 23.70 + if(dot > 1.0) dot = 1.0; 23.71 + 23.72 + angle = acos(dot); 23.73 + sin_angle = sin(angle); 23.74 + 23.75 + if(fabs(sin_angle) < SMALL_NUMBER) { 23.76 + /* for very small angles or completely opposite orientations 23.77 + * use linear interpolation to avoid div/zero (in the first case it makes sense, 23.78 + * the second case is pretty much undefined anyway I guess ... 23.79 + */ 23.80 + a = 1.0f - t; 23.81 + b = t; 23.82 + } else { 23.83 + a = sin((1.0f - t) * angle) / sin_angle; 23.84 + b = sin(t * angle) / sin_angle; 23.85 + } 23.86 + 23.87 + res.x = q1.x * a + q2.x * b; 23.88 + res.y = q1.y * a + q2.y * b; 23.89 + res.z = q1.z * a + q2.z * b; 23.90 + res.w = q1.w * a + q2.w * b; 23.91 + return res; 23.92 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/libs/vmath/ray.cc Sun May 31 00:40:26 2015 +0300 24.3 @@ -0,0 +1,78 @@ 24.4 +/* 24.5 +libvmath - a vector math library 24.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 24.7 + 24.8 +This program is free software: you can redistribute it and/or modify 24.9 +it under the terms of the GNU Lesser General Public License as published 24.10 +by the Free Software Foundation, either version 3 of the License, or 24.11 +(at your option) any later version. 24.12 + 24.13 +This program is distributed in the hope that it will be useful, 24.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 24.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24.16 +GNU Lesser General Public License for more details. 24.17 + 24.18 +You should have received a copy of the GNU Lesser General Public License 24.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 24.20 +*/ 24.21 +#include "ray.h" 24.22 +#include "vector.h" 24.23 + 24.24 +scalar_t Ray::env_ior = 1.0; 24.25 + 24.26 +Ray::Ray() 24.27 +{ 24.28 + ior = env_ior; 24.29 + energy = 1.0; 24.30 + time = 0; 24.31 + iter = 0; 24.32 +} 24.33 + 24.34 +Ray::Ray(const Vector3 &origin, const Vector3 &dir) 24.35 +{ 24.36 + this->origin = origin; 24.37 + this->dir = dir; 24.38 + ior = env_ior; 24.39 + energy = 1.0; 24.40 + time = 0; 24.41 + iter = 0; 24.42 +} 24.43 + 24.44 +void Ray::transform(const Matrix4x4 &xform) 24.45 +{ 24.46 + Matrix4x4 upper = xform; 24.47 + upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0; 24.48 + upper[3][3] = 1.0; 24.49 + 24.50 + dir.transform(upper); 24.51 + origin.transform(xform); 24.52 +} 24.53 + 24.54 +Ray Ray::transformed(const Matrix4x4 &xform) const 24.55 +{ 24.56 + Ray foo = *this; 24.57 + foo.transform(xform); 24.58 + return foo; 24.59 +} 24.60 + 24.61 +void Ray::enter(scalar_t new_ior) 24.62 +{ 24.63 + ior = new_ior; 24.64 +} 24.65 + 24.66 +void Ray::leave() 24.67 +{ 24.68 +} 24.69 + 24.70 +scalar_t Ray::calc_ior(bool entering, scalar_t mat_ior) const 24.71 +{ 24.72 + scalar_t from_ior = this->ior; 24.73 + 24.74 + if(entering) { 24.75 + return from_ior / mat_ior; 24.76 + } 24.77 + 24.78 + Ray tmp = *this; 24.79 + tmp.leave(); 24.80 + return from_ior / tmp.ior; 24.81 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/libs/vmath/ray.h Sun May 31 00:40:26 2015 +0300 25.3 @@ -0,0 +1,68 @@ 25.4 +/* 25.5 +libvmath - a vector math library 25.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 25.7 + 25.8 +This program is free software: you can redistribute it and/or modify 25.9 +it under the terms of the GNU Lesser General Public License as published 25.10 +by the Free Software Foundation, either version 3 of the License, or 25.11 +(at your option) any later version. 25.12 + 25.13 +This program is distributed in the hope that it will be useful, 25.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 25.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25.16 +GNU Lesser General Public License for more details. 25.17 + 25.18 +You should have received a copy of the GNU Lesser General Public License 25.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 25.20 +*/ 25.21 + 25.22 +#ifndef VMATH_RAY_H_ 25.23 +#define VMATH_RAY_H_ 25.24 + 25.25 +#include "matrix.h" 25.26 +#include "vector.h" 25.27 + 25.28 +typedef struct { 25.29 + vec3_t origin, dir; 25.30 +} ray_t; 25.31 + 25.32 +#ifdef __cplusplus 25.33 +extern "C" { 25.34 +#endif /* __cplusplus */ 25.35 + 25.36 +static inline ray_t ray_cons(vec3_t origin, vec3_t dir); 25.37 +ray_t ray_transform(ray_t r, mat4_t m); 25.38 + 25.39 +#ifdef __cplusplus 25.40 +} /* __cplusplus */ 25.41 + 25.42 +class Ray { 25.43 +public: 25.44 + /* enviornmental index of refraction, normally 1.0 */ 25.45 + static scalar_t env_ior; 25.46 + 25.47 + Vector3 origin, dir; 25.48 + scalar_t energy; 25.49 + int iter; 25.50 + scalar_t ior; 25.51 + long time; 25.52 + 25.53 + Ray(); 25.54 + Ray(const Vector3 &origin, const Vector3 &dir); 25.55 + 25.56 + void transform(const Matrix4x4 &xform); 25.57 + Ray transformed(const Matrix4x4 &xform) const; 25.58 + 25.59 + void enter(scalar_t new_ior); 25.60 + void leave(); 25.61 + 25.62 + scalar_t calc_ior(bool entering, scalar_t mat_ior = 1.0) const; 25.63 +}; 25.64 + 25.65 +inline Ray reflect_ray(const Ray &inray, const Vector3 &norm); 25.66 +inline Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t ior, bool entering, scalar_t ray_mag = -1.0); 25.67 +#endif /* __cplusplus */ 25.68 + 25.69 +#include "ray.inl" 25.70 + 25.71 +#endif /* VMATH_RAY_H_ */
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/libs/vmath/ray.inl Sun May 31 00:40:26 2015 +0300 26.3 @@ -0,0 +1,70 @@ 26.4 +/* 26.5 +libvmath - a vector math library 26.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 26.7 + 26.8 +This program is free software: you can redistribute it and/or modify 26.9 +it under the terms of the GNU Lesser General Public License as published 26.10 +by the Free Software Foundation, either version 3 of the License, or 26.11 +(at your option) any later version. 26.12 + 26.13 +This program is distributed in the hope that it will be useful, 26.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 26.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26.16 +GNU Lesser General Public License for more details. 26.17 + 26.18 +You should have received a copy of the GNU Lesser General Public License 26.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 26.20 +*/ 26.21 + 26.22 +#ifdef __cplusplus 26.23 +extern "C" { 26.24 +#endif /* __cplusplus */ 26.25 + 26.26 +static inline ray_t ray_cons(vec3_t origin, vec3_t dir) 26.27 +{ 26.28 + ray_t r; 26.29 + r.origin = origin; 26.30 + r.dir = dir; 26.31 + return r; 26.32 +} 26.33 + 26.34 +#ifdef __cplusplus 26.35 +} 26.36 + 26.37 +inline Ray reflect_ray(const Ray &inray, const Vector3 &norm) 26.38 +{ 26.39 + Ray ray = inray; 26.40 + ray.iter--; 26.41 + ray.dir = ray.dir.reflection(norm); 26.42 + return ray; 26.43 +} 26.44 + 26.45 +inline Ray refract_ray(const Ray &inray, const Vector3 &norm, scalar_t mat_ior, bool entering, scalar_t ray_mag) 26.46 +{ 26.47 + Ray ray = inray; 26.48 + ray.iter--; 26.49 + 26.50 + scalar_t ior = ray.calc_ior(entering, mat_ior); 26.51 + 26.52 + if(entering) { 26.53 + ray.enter(mat_ior); 26.54 + } else { 26.55 + ray.leave(); 26.56 + } 26.57 + 26.58 + if(ray_mag < 0.0) { 26.59 + ray_mag = ray.dir.length(); 26.60 + } 26.61 + ray.dir = (ray.dir / ray_mag).refraction(norm, ior) * ray_mag; 26.62 + 26.63 + /* check TIR */ 26.64 + if(dot_product(ray.dir, norm) > 0.0) { 26.65 + if(entering) { 26.66 + ray.leave(); 26.67 + } else { 26.68 + ray.enter(mat_ior); 26.69 + } 26.70 + } 26.71 + return ray; 26.72 +} 26.73 +#endif /* __cplusplus */
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/libs/vmath/ray_c.c Sun May 31 00:40:26 2015 +0300 27.3 @@ -0,0 +1,36 @@ 27.4 +/* 27.5 +libvmath - a vector math library 27.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 27.7 + 27.8 +This program is free software: you can redistribute it and/or modify 27.9 +it under the terms of the GNU Lesser General Public License as published 27.10 +by the Free Software Foundation, either version 3 of the License, or 27.11 +(at your option) any later version. 27.12 + 27.13 +This program is distributed in the hope that it will be useful, 27.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 27.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27.16 +GNU Lesser General Public License for more details. 27.17 + 27.18 +You should have received a copy of the GNU Lesser General Public License 27.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 27.20 +*/ 27.21 + 27.22 +#include "ray.h" 27.23 +#include "vector.h" 27.24 + 27.25 +ray_t ray_transform(ray_t r, mat4_t xform) 27.26 +{ 27.27 + mat4_t upper; 27.28 + vec3_t dir; 27.29 + 27.30 + m4_copy(upper, xform); 27.31 + upper[0][3] = upper[1][3] = upper[2][3] = upper[3][0] = upper[3][1] = upper[3][2] = 0.0; 27.32 + upper[3][3] = 1.0; 27.33 + 27.34 + dir = v3_sub(r.dir, r.origin); 27.35 + dir = v3_transform(dir, upper); 27.36 + r.origin = v3_transform(r.origin, xform); 27.37 + r.dir = v3_add(dir, r.origin); 27.38 + return r; 27.39 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/libs/vmath/sphvec.cc Sun May 31 00:40:26 2015 +0300 28.3 @@ -0,0 +1,44 @@ 28.4 +/* 28.5 +libvmath - a vector math library 28.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 28.7 + 28.8 +This program is free software: you can redistribute it and/or modify 28.9 +it under the terms of the GNU Lesser General Public License as published 28.10 +by the Free Software Foundation, either version 3 of the License, or 28.11 +(at your option) any later version. 28.12 + 28.13 +This program is distributed in the hope that it will be useful, 28.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 28.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28.16 +GNU Lesser General Public License for more details. 28.17 + 28.18 +You should have received a copy of the GNU Lesser General Public License 28.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 28.20 +*/ 28.21 +#include "sphvec.h" 28.22 +#include "vector.h" 28.23 + 28.24 +/* theta: 0 <= theta <= 2pi, the angle around Y axis. 28.25 + * phi: 0 <= phi <= pi, the angle from Y axis. 28.26 + * r: radius. 28.27 + */ 28.28 +SphVector::SphVector(scalar_t theta, scalar_t phi, scalar_t r) { 28.29 + this->theta = theta; 28.30 + this->phi = phi; 28.31 + this->r = r; 28.32 +} 28.33 + 28.34 +/* Constructs a spherical coordinate vector from a cartesian vector */ 28.35 +SphVector::SphVector(const Vector3 &cvec) { 28.36 + *this = cvec; 28.37 +} 28.38 + 28.39 +/* Assignment operator that converts cartesian to spherical coords */ 28.40 +SphVector &SphVector::operator =(const Vector3 &cvec) { 28.41 + r = cvec.length(); 28.42 + //theta = atan2(cvec.y, cvec.x); 28.43 + theta = atan2(cvec.z, cvec.x); 28.44 + //phi = acos(cvec.z / r); 28.45 + phi = acos(cvec.y / r); 28.46 + return *this; 28.47 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/libs/vmath/sphvec.h Sun May 31 00:40:26 2015 +0300 29.3 @@ -0,0 +1,36 @@ 29.4 +/* 29.5 +libvmath - a vector math library 29.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 29.7 + 29.8 +This program is free software: you can redistribute it and/or modify 29.9 +it under the terms of the GNU Lesser General Public License as published 29.10 +by the Free Software Foundation, either version 3 of the License, or 29.11 +(at your option) any later version. 29.12 + 29.13 +This program is distributed in the hope that it will be useful, 29.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 29.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29.16 +GNU Lesser General Public License for more details. 29.17 + 29.18 +You should have received a copy of the GNU Lesser General Public License 29.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 29.20 +*/ 29.21 + 29.22 +#ifndef VMATH_SPHVEC_H_ 29.23 +#define VMATH_SPHVEC_H_ 29.24 + 29.25 +#include "vmath_types.h" 29.26 + 29.27 +#ifdef __cplusplus 29.28 +/* Vector in spherical coordinates */ 29.29 +class SphVector { 29.30 +public: 29.31 + scalar_t theta, phi, r; 29.32 + 29.33 + SphVector(scalar_t theta = 0.0, scalar_t phi = 0.0, scalar_t r = 1.0); 29.34 + SphVector(const Vector3 &cvec); 29.35 + SphVector &operator =(const Vector3 &cvec); 29.36 +}; 29.37 +#endif /* __cplusplus */ 29.38 + 29.39 +#endif /* VMATH_SPHVEC_H_ */
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/libs/vmath/vector.cc Sun May 31 00:40:26 2015 +0300 30.3 @@ -0,0 +1,348 @@ 30.4 +/* 30.5 +libvmath - a vector math library 30.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 30.7 + 30.8 +This program is free software: you can redistribute it and/or modify 30.9 +it under the terms of the GNU Lesser General Public License as published 30.10 +by the Free Software Foundation, either version 3 of the License, or 30.11 +(at your option) any later version. 30.12 + 30.13 +This program is distributed in the hope that it will be useful, 30.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 30.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30.16 +GNU Lesser General Public License for more details. 30.17 + 30.18 +You should have received a copy of the GNU Lesser General Public License 30.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 30.20 +*/ 30.21 +#include "vector.h" 30.22 +#include "vmath.h" 30.23 + 30.24 +// ---------- Vector2 ----------- 30.25 + 30.26 +Vector2::Vector2(scalar_t x, scalar_t y) 30.27 +{ 30.28 + this->x = x; 30.29 + this->y = y; 30.30 +} 30.31 + 30.32 +Vector2::Vector2(const vec2_t &vec) 30.33 +{ 30.34 + x = vec.x; 30.35 + y = vec.y; 30.36 +} 30.37 + 30.38 +Vector2::Vector2(const Vector3 &vec) 30.39 +{ 30.40 + x = vec.x; 30.41 + y = vec.y; 30.42 +} 30.43 + 30.44 +Vector2::Vector2(const Vector4 &vec) 30.45 +{ 30.46 + x = vec.x; 30.47 + y = vec.y; 30.48 +} 30.49 + 30.50 +void Vector2::normalize() 30.51 +{ 30.52 + scalar_t len = length(); 30.53 + x /= len; 30.54 + y /= len; 30.55 +} 30.56 + 30.57 +Vector2 Vector2::normalized() const 30.58 +{ 30.59 + scalar_t len = length(); 30.60 + return Vector2(x / len, y / len); 30.61 +} 30.62 + 30.63 +void Vector2::transform(const Matrix3x3 &mat) 30.64 +{ 30.65 + scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2]; 30.66 + y = mat[1][0] * x + mat[1][1] * y + mat[1][2]; 30.67 + x = nx; 30.68 +} 30.69 + 30.70 +Vector2 Vector2::transformed(const Matrix3x3 &mat) const 30.71 +{ 30.72 + Vector2 vec; 30.73 + vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2]; 30.74 + vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2]; 30.75 + return vec; 30.76 +} 30.77 + 30.78 +void Vector2::rotate(scalar_t angle) 30.79 +{ 30.80 + *this = Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y); 30.81 +} 30.82 + 30.83 +Vector2 Vector2::rotated(scalar_t angle) const 30.84 +{ 30.85 + return Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y); 30.86 +} 30.87 + 30.88 +Vector2 Vector2::reflection(const Vector2 &normal) const 30.89 +{ 30.90 + return 2.0 * dot_product(*this, normal) * normal - *this; 30.91 +} 30.92 + 30.93 +Vector2 Vector2::refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const 30.94 +{ 30.95 + // quick and dirty implementation :) 30.96 + Vector3 v3refr = Vector3(this->x, this->y, 1.0).refraction(Vector3(this->x, this->y, 1), src_ior, dst_ior); 30.97 + return Vector2(v3refr.x, v3refr.y); 30.98 +} 30.99 + 30.100 +/* 30.101 +std::ostream &operator <<(std::ostream &out, const Vector2 &vec) 30.102 +{ 30.103 + out << "[" << vec.x << " " << vec.y << "]"; 30.104 + return out; 30.105 +} 30.106 +*/ 30.107 + 30.108 + 30.109 +// --------- Vector3 ---------- 30.110 + 30.111 +Vector3::Vector3(scalar_t x, scalar_t y, scalar_t z) 30.112 +{ 30.113 + this->x = x; 30.114 + this->y = y; 30.115 + this->z = z; 30.116 +} 30.117 + 30.118 +Vector3::Vector3(const vec3_t &vec) 30.119 +{ 30.120 + x = vec.x; 30.121 + y = vec.y; 30.122 + z = vec.z; 30.123 +} 30.124 + 30.125 +Vector3::Vector3(const Vector2 &vec) 30.126 +{ 30.127 + x = vec.x; 30.128 + y = vec.y; 30.129 + z = 1; 30.130 +} 30.131 + 30.132 +Vector3::Vector3(const Vector4 &vec) 30.133 +{ 30.134 + x = vec.x; 30.135 + y = vec.y; 30.136 + z = vec.z; 30.137 +} 30.138 + 30.139 +Vector3::Vector3(const SphVector &sph) 30.140 +{ 30.141 + *this = sph; 30.142 +} 30.143 + 30.144 +Vector3 &Vector3::operator =(const SphVector &sph) 30.145 +{ 30.146 + x = sph.r * cos(sph.theta) * sin(sph.phi); 30.147 + z = sph.r * sin(sph.theta) * sin(sph.phi); 30.148 + y = sph.r * cos(sph.phi); 30.149 + return *this; 30.150 +} 30.151 + 30.152 +void Vector3::normalize() 30.153 +{ 30.154 + scalar_t len = length(); 30.155 + x /= len; 30.156 + y /= len; 30.157 + z /= len; 30.158 +} 30.159 + 30.160 +Vector3 Vector3::normalized() const 30.161 +{ 30.162 + scalar_t len = length(); 30.163 + return Vector3(x / len, y / len, z / len); 30.164 +} 30.165 + 30.166 +Vector3 Vector3::reflection(const Vector3 &normal) const 30.167 +{ 30.168 + return 2.0 * dot_product(*this, normal) * normal - *this; 30.169 +} 30.170 + 30.171 +Vector3 Vector3::refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const 30.172 +{ 30.173 + return refraction(normal, src_ior / dst_ior); 30.174 +} 30.175 + 30.176 +Vector3 Vector3::refraction(const Vector3 &normal, scalar_t ior) const 30.177 +{ 30.178 + scalar_t cos_inc = dot_product(*this, -normal); 30.179 + 30.180 + scalar_t radical = 1.0 + SQ(ior) * (SQ(cos_inc) - 1.0); 30.181 + 30.182 + if(radical < 0.0) { // total internal reflection 30.183 + return -reflection(normal); 30.184 + } 30.185 + 30.186 + scalar_t beta = ior * cos_inc - sqrt(radical); 30.187 + 30.188 + return *this * ior + normal * beta; 30.189 +} 30.190 + 30.191 +void Vector3::transform(const Matrix3x3 &mat) 30.192 +{ 30.193 + scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z; 30.194 + scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z; 30.195 + z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z; 30.196 + x = nx; 30.197 + y = ny; 30.198 +} 30.199 + 30.200 +Vector3 Vector3::transformed(const Matrix3x3 &mat) const 30.201 +{ 30.202 + Vector3 vec; 30.203 + vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z; 30.204 + vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z; 30.205 + vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z; 30.206 + return vec; 30.207 +} 30.208 + 30.209 +void Vector3::transform(const Matrix4x4 &mat) 30.210 +{ 30.211 + scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]; 30.212 + scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]; 30.213 + z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]; 30.214 + x = nx; 30.215 + y = ny; 30.216 +} 30.217 + 30.218 +Vector3 Vector3::transformed(const Matrix4x4 &mat) const 30.219 +{ 30.220 + Vector3 vec; 30.221 + vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3]; 30.222 + vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3]; 30.223 + vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3]; 30.224 + return vec; 30.225 +} 30.226 + 30.227 +void Vector3::transform(const Quaternion &quat) 30.228 +{ 30.229 + Quaternion vq(0.0f, *this); 30.230 + vq = quat * vq * quat.inverse(); 30.231 + *this = vq.v; 30.232 +} 30.233 + 30.234 +Vector3 Vector3::transformed(const Quaternion &quat) const 30.235 +{ 30.236 + Quaternion vq(0.0f, *this); 30.237 + vq = quat * vq * quat.inverse(); 30.238 + return vq.v; 30.239 +} 30.240 + 30.241 +void Vector3::rotate(const Vector3 &euler) 30.242 +{ 30.243 + Matrix4x4 rot; 30.244 + rot.set_rotation(euler); 30.245 + transform(rot); 30.246 +} 30.247 + 30.248 +Vector3 Vector3::rotated(const Vector3 &euler) const 30.249 +{ 30.250 + Matrix4x4 rot; 30.251 + rot.set_rotation(euler); 30.252 + return transformed(rot); 30.253 +} 30.254 + 30.255 +/* 30.256 +std::ostream &operator <<(std::ostream &out, const Vector3 &vec) 30.257 +{ 30.258 + out << "[" << vec.x << " " << vec.y << " " << vec.z << "]"; 30.259 + return out; 30.260 +} 30.261 +*/ 30.262 + 30.263 + 30.264 +// -------------- Vector4 -------------- 30.265 +Vector4::Vector4(scalar_t x, scalar_t y, scalar_t z, scalar_t w) 30.266 +{ 30.267 + this->x = x; 30.268 + this->y = y; 30.269 + this->z = z; 30.270 + this->w = w; 30.271 +} 30.272 + 30.273 +Vector4::Vector4(const vec4_t &vec) 30.274 +{ 30.275 + x = vec.x; 30.276 + y = vec.y; 30.277 + z = vec.z; 30.278 + w = vec.w; 30.279 +} 30.280 + 30.281 +Vector4::Vector4(const Vector2 &vec) 30.282 +{ 30.283 + x = vec.x; 30.284 + y = vec.y; 30.285 + z = 1; 30.286 + w = 1; 30.287 +} 30.288 + 30.289 +Vector4::Vector4(const Vector3 &vec) 30.290 +{ 30.291 + x = vec.x; 30.292 + y = vec.y; 30.293 + z = vec.z; 30.294 + w = 1; 30.295 +} 30.296 + 30.297 +void Vector4::normalize() 30.298 +{ 30.299 + scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w); 30.300 + x /= len; 30.301 + y /= len; 30.302 + z /= len; 30.303 + w /= len; 30.304 +} 30.305 + 30.306 +Vector4 Vector4::normalized() const 30.307 +{ 30.308 + scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w); 30.309 + return Vector4(x / len, y / len, z / len, w / len); 30.310 +} 30.311 + 30.312 +void Vector4::transform(const Matrix4x4 &mat) 30.313 +{ 30.314 + scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w; 30.315 + scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w; 30.316 + scalar_t nz = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w; 30.317 + w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w; 30.318 + x = nx; 30.319 + y = ny; 30.320 + z = nz; 30.321 +} 30.322 + 30.323 +Vector4 Vector4::transformed(const Matrix4x4 &mat) const 30.324 +{ 30.325 + Vector4 vec; 30.326 + vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w; 30.327 + vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w; 30.328 + vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w; 30.329 + vec.w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w; 30.330 + return vec; 30.331 +} 30.332 + 30.333 +// TODO: implement 4D vector reflection 30.334 +Vector4 Vector4::reflection(const Vector4 &normal) const 30.335 +{ 30.336 + return *this; 30.337 +} 30.338 + 30.339 +// TODO: implement 4D vector refraction 30.340 +Vector4 Vector4::refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const 30.341 +{ 30.342 + return *this; 30.343 +} 30.344 + 30.345 +/* 30.346 +std::ostream &operator <<(std::ostream &out, const Vector4 &vec) 30.347 +{ 30.348 + out << "[" << vec.x << " " << vec.y << " " << vec.z << " " << vec.w << "]"; 30.349 + return out; 30.350 +} 30.351 +*/
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/libs/vmath/vector.h Sun May 31 00:40:26 2015 +0300 31.3 @@ -0,0 +1,294 @@ 31.4 +/* 31.5 +libvmath - a vector math library 31.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 31.7 + 31.8 +This program is free software: you can redistribute it and/or modify 31.9 +it under the terms of the GNU Lesser General Public License as published 31.10 +by the Free Software Foundation, either version 3 of the License, or 31.11 +(at your option) any later version. 31.12 + 31.13 +This program is distributed in the hope that it will be useful, 31.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 31.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31.16 +GNU Lesser General Public License for more details. 31.17 + 31.18 +You should have received a copy of the GNU Lesser General Public License 31.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 31.20 +*/ 31.21 + 31.22 +#ifndef VMATH_VECTOR_H_ 31.23 +#define VMATH_VECTOR_H_ 31.24 + 31.25 +#include <stdio.h> 31.26 +#include "vmath_types.h" 31.27 + 31.28 +#ifdef __cplusplus 31.29 +extern "C" { 31.30 +#endif /* __cplusplus */ 31.31 + 31.32 +/* C 2D vector functions */ 31.33 +static inline vec2_t v2_cons(scalar_t x, scalar_t y); 31.34 +static inline void v2_print(FILE *fp, vec2_t v); 31.35 + 31.36 +static inline vec2_t v2_add(vec2_t v1, vec2_t v2); 31.37 +static inline vec2_t v2_sub(vec2_t v1, vec2_t v2); 31.38 +static inline vec2_t v2_scale(vec2_t v, scalar_t s); 31.39 +static inline scalar_t v2_dot(vec2_t v1, vec2_t v2); 31.40 +static inline scalar_t v2_length(vec2_t v); 31.41 +static inline scalar_t v2_length_sq(vec2_t v); 31.42 +static inline vec2_t v2_normalize(vec2_t v); 31.43 + 31.44 +static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t); 31.45 + 31.46 +/* C 3D vector functions */ 31.47 +static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z); 31.48 +static inline void v3_print(FILE *fp, vec3_t v); 31.49 + 31.50 +static inline vec3_t v3_add(vec3_t v1, vec3_t v2); 31.51 +static inline vec3_t v3_sub(vec3_t v1, vec3_t v2); 31.52 +static inline vec3_t v3_neg(vec3_t v); 31.53 +static inline vec3_t v3_mul(vec3_t v1, vec3_t v2); 31.54 +static inline vec3_t v3_scale(vec3_t v1, scalar_t s); 31.55 +static inline scalar_t v3_dot(vec3_t v1, vec3_t v2); 31.56 +static inline vec3_t v3_cross(vec3_t v1, vec3_t v2); 31.57 +static inline scalar_t v3_length(vec3_t v); 31.58 +static inline scalar_t v3_length_sq(vec3_t v); 31.59 +static inline vec3_t v3_normalize(vec3_t v); 31.60 +static inline vec3_t v3_transform(vec3_t v, mat4_t m); 31.61 + 31.62 +static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z); 31.63 +static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z); 31.64 +static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q); 31.65 + 31.66 +static inline vec3_t v3_reflect(vec3_t v, vec3_t n); 31.67 + 31.68 +static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t); 31.69 + 31.70 +/* C 4D vector functions */ 31.71 +static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w); 31.72 +static inline void v4_print(FILE *fp, vec4_t v); 31.73 + 31.74 +static inline vec4_t v4_add(vec4_t v1, vec4_t v2); 31.75 +static inline vec4_t v4_sub(vec4_t v1, vec4_t v2); 31.76 +static inline vec4_t v4_neg(vec4_t v); 31.77 +static inline vec4_t v4_mul(vec4_t v1, vec4_t v2); 31.78 +static inline vec4_t v4_scale(vec4_t v, scalar_t s); 31.79 +static inline scalar_t v4_dot(vec4_t v1, vec4_t v2); 31.80 +static inline scalar_t v4_length(vec4_t v); 31.81 +static inline scalar_t v4_length_sq(vec4_t v); 31.82 +static inline vec4_t v4_normalize(vec4_t v); 31.83 +static inline vec4_t v4_transform(vec4_t v, mat4_t m); 31.84 + 31.85 +#ifdef __cplusplus 31.86 +} /* extern "C" */ 31.87 + 31.88 +/* when included from C++ source files, also define the vector classes */ 31.89 + 31.90 +/** 2D Vector */ 31.91 +class Vector2 { 31.92 +public: 31.93 + scalar_t x, y; 31.94 + 31.95 + Vector2(scalar_t x = 0.0, scalar_t y = 0.0); 31.96 + Vector2(const vec2_t &vec); 31.97 + Vector2(const Vector3 &vec); 31.98 + Vector2(const Vector4 &vec); 31.99 + 31.100 + inline scalar_t &operator [](int elem); 31.101 + inline const scalar_t &operator [](int elem) const; 31.102 + 31.103 + inline scalar_t length() const; 31.104 + inline scalar_t length_sq() const; 31.105 + void normalize(); 31.106 + Vector2 normalized() const; 31.107 + 31.108 + void transform(const Matrix3x3 &mat); 31.109 + Vector2 transformed(const Matrix3x3 &mat) const; 31.110 + 31.111 + void rotate(scalar_t angle); 31.112 + Vector2 rotated(scalar_t angle) const; 31.113 + 31.114 + Vector2 reflection(const Vector2 &normal) const; 31.115 + Vector2 refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const; 31.116 +}; 31.117 + 31.118 +/* unary operations */ 31.119 +inline Vector2 operator -(const Vector2 &vec); 31.120 + 31.121 +/* binary vector (op) vector operations */ 31.122 +inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2); 31.123 + 31.124 +inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2); 31.125 +inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2); 31.126 +inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2); 31.127 +inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2); 31.128 +inline bool operator ==(const Vector2 &v1, const Vector2 &v2); 31.129 + 31.130 +inline void operator +=(Vector2 &v1, const Vector2 &v2); 31.131 +inline void operator -=(Vector2 &v1, const Vector2 &v2); 31.132 +inline void operator *=(Vector2 &v1, const Vector2 &v2); 31.133 +inline void operator /=(Vector2 &v1, const Vector2 &v2); 31.134 + 31.135 +/* binary vector (op) scalar and scalar (op) vector operations */ 31.136 +inline Vector2 operator +(const Vector2 &vec, scalar_t scalar); 31.137 +inline Vector2 operator +(scalar_t scalar, const Vector2 &vec); 31.138 +inline Vector2 operator -(const Vector2 &vec, scalar_t scalar); 31.139 +inline Vector2 operator *(const Vector2 &vec, scalar_t scalar); 31.140 +inline Vector2 operator *(scalar_t scalar, const Vector2 &vec); 31.141 +inline Vector2 operator /(const Vector2 &vec, scalar_t scalar); 31.142 + 31.143 +inline void operator +=(Vector2 &vec, scalar_t scalar); 31.144 +inline void operator -=(Vector2 &vec, scalar_t scalar); 31.145 +inline void operator *=(Vector2 &vec, scalar_t scalar); 31.146 +inline void operator /=(Vector2 &vec, scalar_t scalar); 31.147 + 31.148 + 31.149 +inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t); 31.150 +inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1, 31.151 + const Vector2 &v2, const Vector2 &v3, scalar_t t); 31.152 +inline Vector2 bspline(const Vector2 &v0, const Vector2 &v1, 31.153 + const Vector2 &v2, const Vector2 &v3, scalar_t t); 31.154 + 31.155 +/* 3D Vector */ 31.156 +class Vector3 { 31.157 +public: 31.158 + scalar_t x, y, z; 31.159 + 31.160 + Vector3(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0); 31.161 + Vector3(const vec3_t &vec); 31.162 + Vector3(const Vector2 &vec); 31.163 + Vector3(const Vector4 &vec); 31.164 + Vector3(const SphVector &sph); 31.165 + 31.166 + Vector3 &operator =(const SphVector &sph); 31.167 + 31.168 + inline scalar_t &operator [](int elem); 31.169 + inline const scalar_t &operator [](int elem) const; 31.170 + 31.171 + inline scalar_t length() const; 31.172 + inline scalar_t length_sq() const; 31.173 + void normalize(); 31.174 + Vector3 normalized() const; 31.175 + 31.176 + void transform(const Matrix3x3 &mat); 31.177 + Vector3 transformed(const Matrix3x3 &mat) const; 31.178 + void transform(const Matrix4x4 &mat); 31.179 + Vector3 transformed(const Matrix4x4 &mat) const; 31.180 + void transform(const Quaternion &quat); 31.181 + Vector3 transformed(const Quaternion &quat) const; 31.182 + 31.183 + void rotate(const Vector3 &euler); 31.184 + Vector3 rotated(const Vector3 &euler) const; 31.185 + 31.186 + Vector3 reflection(const Vector3 &normal) const; 31.187 + Vector3 refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const; 31.188 + Vector3 refraction(const Vector3 &normal, scalar_t ior) const; 31.189 +}; 31.190 + 31.191 +/* unary operations */ 31.192 +inline Vector3 operator -(const Vector3 &vec); 31.193 + 31.194 +/* binary vector (op) vector operations */ 31.195 +inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2); 31.196 +inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2); 31.197 + 31.198 +inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2); 31.199 +inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2); 31.200 +inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2); 31.201 +inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2); 31.202 +inline bool operator ==(const Vector3 &v1, const Vector3 &v2); 31.203 + 31.204 +inline void operator +=(Vector3 &v1, const Vector3 &v2); 31.205 +inline void operator -=(Vector3 &v1, const Vector3 &v2); 31.206 +inline void operator *=(Vector3 &v1, const Vector3 &v2); 31.207 +inline void operator /=(Vector3 &v1, const Vector3 &v2); 31.208 + 31.209 +/* binary vector (op) scalar and scalar (op) vector operations */ 31.210 +inline Vector3 operator +(const Vector3 &vec, scalar_t scalar); 31.211 +inline Vector3 operator +(scalar_t scalar, const Vector3 &vec); 31.212 +inline Vector3 operator -(const Vector3 &vec, scalar_t scalar); 31.213 +inline Vector3 operator *(const Vector3 &vec, scalar_t scalar); 31.214 +inline Vector3 operator *(scalar_t scalar, const Vector3 &vec); 31.215 +inline Vector3 operator /(const Vector3 &vec, scalar_t scalar); 31.216 + 31.217 +inline void operator +=(Vector3 &vec, scalar_t scalar); 31.218 +inline void operator -=(Vector3 &vec, scalar_t scalar); 31.219 +inline void operator *=(Vector3 &vec, scalar_t scalar); 31.220 +inline void operator /=(Vector3 &vec, scalar_t scalar); 31.221 + 31.222 + 31.223 +inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t); 31.224 +inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1, 31.225 + const Vector3 &v2, const Vector3 &v3, scalar_t t); 31.226 +inline Vector3 bspline(const Vector3 &v0, const Vector3 &v1, 31.227 + const Vector3 &v2, const Vector3 &v3, scalar_t t); 31.228 + 31.229 +/* 4D Vector */ 31.230 +class Vector4 { 31.231 +public: 31.232 + scalar_t x, y, z, w; 31.233 + 31.234 + Vector4(scalar_t x = 0.0, scalar_t y = 0.0, scalar_t z = 0.0, scalar_t w = 0.0); 31.235 + Vector4(const vec4_t &vec); 31.236 + Vector4(const Vector2 &vec); 31.237 + Vector4(const Vector3 &vec); 31.238 + 31.239 + inline scalar_t &operator [](int elem); 31.240 + inline const scalar_t &operator [](int elem) const; 31.241 + 31.242 + inline scalar_t length() const; 31.243 + inline scalar_t length_sq() const; 31.244 + void normalize(); 31.245 + Vector4 normalized() const; 31.246 + 31.247 + void transform(const Matrix4x4 &mat); 31.248 + Vector4 transformed(const Matrix4x4 &mat) const; 31.249 + 31.250 + Vector4 reflection(const Vector4 &normal) const; 31.251 + Vector4 refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const; 31.252 +}; 31.253 + 31.254 + 31.255 +/* unary operations */ 31.256 +inline Vector4 operator -(const Vector4 &vec); 31.257 + 31.258 +/* binary vector (op) vector operations */ 31.259 +inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2); 31.260 +inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3); 31.261 + 31.262 +inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2); 31.263 +inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2); 31.264 +inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2); 31.265 +inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2); 31.266 +inline bool operator ==(const Vector4 &v1, const Vector4 &v2); 31.267 + 31.268 +inline void operator +=(Vector4 &v1, const Vector4 &v2); 31.269 +inline void operator -=(Vector4 &v1, const Vector4 &v2); 31.270 +inline void operator *=(Vector4 &v1, const Vector4 &v2); 31.271 +inline void operator /=(Vector4 &v1, const Vector4 &v2); 31.272 + 31.273 +/* binary vector (op) scalar and scalar (op) vector operations */ 31.274 +inline Vector4 operator +(const Vector4 &vec, scalar_t scalar); 31.275 +inline Vector4 operator +(scalar_t scalar, const Vector4 &vec); 31.276 +inline Vector4 operator -(const Vector4 &vec, scalar_t scalar); 31.277 +inline Vector4 operator *(const Vector4 &vec, scalar_t scalar); 31.278 +inline Vector4 operator *(scalar_t scalar, const Vector4 &vec); 31.279 +inline Vector4 operator /(const Vector4 &vec, scalar_t scalar); 31.280 + 31.281 +inline void operator +=(Vector4 &vec, scalar_t scalar); 31.282 +inline void operator -=(Vector4 &vec, scalar_t scalar); 31.283 +inline void operator *=(Vector4 &vec, scalar_t scalar); 31.284 +inline void operator /=(Vector4 &vec, scalar_t scalar); 31.285 + 31.286 + 31.287 +inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t); 31.288 +inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1, 31.289 + const Vector4 &v2, const Vector4 &v3, scalar_t t); 31.290 +inline Vector4 bspline(const Vector4 &v0, const Vector4 &v1, 31.291 + const Vector4 &v2, const Vector4 &v3, scalar_t t); 31.292 + 31.293 +#endif /* __cplusplus */ 31.294 + 31.295 +#include "vector.inl" 31.296 + 31.297 +#endif /* VMATH_VECTOR_H_ */
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/libs/vmath/vector.inl Sun May 31 00:40:26 2015 +0300 32.3 @@ -0,0 +1,812 @@ 32.4 +/* 32.5 +libvmath - a vector math library 32.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 32.7 + 32.8 +This program is free software: you can redistribute it and/or modify 32.9 +it under the terms of the GNU Lesser General Public License as published 32.10 +by the Free Software Foundation, either version 3 of the License, or 32.11 +(at your option) any later version. 32.12 + 32.13 +This program is distributed in the hope that it will be useful, 32.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 32.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32.16 +GNU Lesser General Public License for more details. 32.17 + 32.18 +You should have received a copy of the GNU Lesser General Public License 32.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 32.20 +*/ 32.21 + 32.22 +#include <math.h> 32.23 + 32.24 +#ifdef __cplusplus 32.25 +extern "C" { 32.26 +#endif /* __cplusplus */ 32.27 + 32.28 +scalar_t spline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t); 32.29 +scalar_t bspline(scalar_t, scalar_t, scalar_t, scalar_t, scalar_t); 32.30 + 32.31 +/* C 2D vector functions */ 32.32 +static inline vec2_t v2_cons(scalar_t x, scalar_t y) 32.33 +{ 32.34 + vec2_t v; 32.35 + v.x = x; 32.36 + v.y = y; 32.37 + return v; 32.38 +} 32.39 + 32.40 +static inline void v2_print(FILE *fp, vec2_t v) 32.41 +{ 32.42 + fprintf(fp, "[ %.4f %.4f ]", v.x, v.y); 32.43 +} 32.44 + 32.45 +static inline vec2_t v2_add(vec2_t v1, vec2_t v2) 32.46 +{ 32.47 + vec2_t res; 32.48 + res.x = v1.x + v2.x; 32.49 + res.y = v1.y + v2.y; 32.50 + return res; 32.51 +} 32.52 + 32.53 +static inline vec2_t v2_sub(vec2_t v1, vec2_t v2) 32.54 +{ 32.55 + vec2_t res; 32.56 + res.x = v1.x - v2.x; 32.57 + res.y = v1.y - v2.y; 32.58 + return res; 32.59 +} 32.60 + 32.61 +static inline vec2_t v2_scale(vec2_t v, scalar_t s) 32.62 +{ 32.63 + vec2_t res; 32.64 + res.x = v.x * s; 32.65 + res.y = v.y * s; 32.66 + return res; 32.67 +} 32.68 + 32.69 +static inline scalar_t v2_dot(vec2_t v1, vec2_t v2) 32.70 +{ 32.71 + return v1.x * v2.x + v1.y * v2.y; 32.72 +} 32.73 + 32.74 +static inline scalar_t v2_length(vec2_t v) 32.75 +{ 32.76 + return sqrt(v.x * v.x + v.y * v.y); 32.77 +} 32.78 + 32.79 +static inline scalar_t v2_length_sq(vec2_t v) 32.80 +{ 32.81 + return v.x * v.x + v.y * v.y; 32.82 +} 32.83 + 32.84 +static inline vec2_t v2_normalize(vec2_t v) 32.85 +{ 32.86 + scalar_t len = (scalar_t)sqrt(v.x * v.x + v.y * v.y); 32.87 + v.x /= len; 32.88 + v.y /= len; 32.89 + return v; 32.90 +} 32.91 + 32.92 +static inline vec2_t v2_lerp(vec2_t v1, vec2_t v2, scalar_t t) 32.93 +{ 32.94 + vec2_t res; 32.95 + res.x = v1.x + (v2.x - v1.x) * t; 32.96 + res.y = v1.y + (v2.y - v1.y) * t; 32.97 + return res; 32.98 +} 32.99 + 32.100 + 32.101 +/* C 3D vector functions */ 32.102 +static inline vec3_t v3_cons(scalar_t x, scalar_t y, scalar_t z) 32.103 +{ 32.104 + vec3_t v; 32.105 + v.x = x; 32.106 + v.y = y; 32.107 + v.z = z; 32.108 + return v; 32.109 +} 32.110 + 32.111 +static inline void v3_print(FILE *fp, vec3_t v) 32.112 +{ 32.113 + fprintf(fp, "[ %.4f %.4f %.4f ]", v.x, v.y, v.z); 32.114 +} 32.115 + 32.116 +static inline vec3_t v3_add(vec3_t v1, vec3_t v2) 32.117 +{ 32.118 + v1.x += v2.x; 32.119 + v1.y += v2.y; 32.120 + v1.z += v2.z; 32.121 + return v1; 32.122 +} 32.123 + 32.124 +static inline vec3_t v3_sub(vec3_t v1, vec3_t v2) 32.125 +{ 32.126 + v1.x -= v2.x; 32.127 + v1.y -= v2.y; 32.128 + v1.z -= v2.z; 32.129 + return v1; 32.130 +} 32.131 + 32.132 +static inline vec3_t v3_neg(vec3_t v) 32.133 +{ 32.134 + v.x = -v.x; 32.135 + v.y = -v.y; 32.136 + v.z = -v.z; 32.137 + return v; 32.138 +} 32.139 + 32.140 +static inline vec3_t v3_mul(vec3_t v1, vec3_t v2) 32.141 +{ 32.142 + v1.x *= v2.x; 32.143 + v1.y *= v2.y; 32.144 + v1.z *= v2.z; 32.145 + return v1; 32.146 +} 32.147 + 32.148 +static inline vec3_t v3_scale(vec3_t v1, scalar_t s) 32.149 +{ 32.150 + v1.x *= s; 32.151 + v1.y *= s; 32.152 + v1.z *= s; 32.153 + return v1; 32.154 +} 32.155 + 32.156 +static inline scalar_t v3_dot(vec3_t v1, vec3_t v2) 32.157 +{ 32.158 + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; 32.159 +} 32.160 + 32.161 +static inline vec3_t v3_cross(vec3_t v1, vec3_t v2) 32.162 +{ 32.163 + vec3_t v; 32.164 + v.x = v1.y * v2.z - v1.z * v2.y; 32.165 + v.y = v1.z * v2.x - v1.x * v2.z; 32.166 + v.z = v1.x * v2.y - v1.y * v2.x; 32.167 + return v; 32.168 +} 32.169 + 32.170 +static inline scalar_t v3_length(vec3_t v) 32.171 +{ 32.172 + return sqrt(v.x * v.x + v.y * v.y + v.z * v.z); 32.173 +} 32.174 + 32.175 +static inline scalar_t v3_length_sq(vec3_t v) 32.176 +{ 32.177 + return v.x * v.x + v.y * v.y + v.z * v.z; 32.178 +} 32.179 + 32.180 +static inline vec3_t v3_normalize(vec3_t v) 32.181 +{ 32.182 + scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z); 32.183 + v.x /= len; 32.184 + v.y /= len; 32.185 + v.z /= len; 32.186 + return v; 32.187 +} 32.188 + 32.189 +static inline vec3_t v3_transform(vec3_t v, mat4_t m) 32.190 +{ 32.191 + vec3_t res; 32.192 + res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3]; 32.193 + res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3]; 32.194 + res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]; 32.195 + return res; 32.196 +} 32.197 + 32.198 +static inline vec3_t v3_rotate(vec3_t v, scalar_t x, scalar_t y, scalar_t z) 32.199 +{ 32.200 + void m4_rotate(mat4_t, scalar_t, scalar_t, scalar_t); 32.201 + 32.202 + mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; 32.203 + m4_rotate(m, x, y, z); 32.204 + return v3_transform(v, m); 32.205 +} 32.206 + 32.207 +static inline vec3_t v3_rotate_axis(vec3_t v, scalar_t angle, scalar_t x, scalar_t y, scalar_t z) 32.208 +{ 32.209 + void m4_rotate_axis(mat4_t, scalar_t, scalar_t, scalar_t, scalar_t); 32.210 + 32.211 + mat4_t m = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; 32.212 + m4_rotate_axis(m, angle, x, y, z); 32.213 + return v3_transform(v, m); 32.214 +} 32.215 + 32.216 +static inline vec3_t v3_rotate_quat(vec3_t v, quat_t q) 32.217 +{ 32.218 + quat_t quat_rotate_quat(quat_t, quat_t); 32.219 + 32.220 + quat_t vq = v4_cons(v.x, v.y, v.z, 0.0); 32.221 + quat_t res = quat_rotate_quat(vq, q); 32.222 + return v3_cons(res.x, res.y, res.z); 32.223 +} 32.224 + 32.225 +static inline vec3_t v3_reflect(vec3_t v, vec3_t n) 32.226 +{ 32.227 + scalar_t dot = v3_dot(v, n); 32.228 + return v3_sub(v3_scale(n, dot * 2.0), v); 32.229 +} 32.230 + 32.231 +static inline vec3_t v3_lerp(vec3_t v1, vec3_t v2, scalar_t t) 32.232 +{ 32.233 + v1.x += (v2.x - v1.x) * t; 32.234 + v1.y += (v2.y - v1.y) * t; 32.235 + v1.z += (v2.z - v1.z) * t; 32.236 + return v1; 32.237 +} 32.238 + 32.239 +/* C 4D vector functions */ 32.240 +static inline vec4_t v4_cons(scalar_t x, scalar_t y, scalar_t z, scalar_t w) 32.241 +{ 32.242 + vec4_t v; 32.243 + v.x = x; 32.244 + v.y = y; 32.245 + v.z = z; 32.246 + v.w = w; 32.247 + return v; 32.248 +} 32.249 + 32.250 +static inline void v4_print(FILE *fp, vec4_t v) 32.251 +{ 32.252 + fprintf(fp, "[ %.4f %.4f %.4f %.4f ]", v.x, v.y, v.z, v.w); 32.253 +} 32.254 + 32.255 +static inline vec4_t v4_add(vec4_t v1, vec4_t v2) 32.256 +{ 32.257 + v1.x += v2.x; 32.258 + v1.y += v2.y; 32.259 + v1.z += v2.z; 32.260 + v1.w += v2.w; 32.261 + return v1; 32.262 +} 32.263 + 32.264 +static inline vec4_t v4_sub(vec4_t v1, vec4_t v2) 32.265 +{ 32.266 + v1.x -= v2.x; 32.267 + v1.y -= v2.y; 32.268 + v1.z -= v2.z; 32.269 + v1.w -= v2.w; 32.270 + return v1; 32.271 +} 32.272 + 32.273 +static inline vec4_t v4_neg(vec4_t v) 32.274 +{ 32.275 + v.x = -v.x; 32.276 + v.y = -v.y; 32.277 + v.z = -v.z; 32.278 + v.w = -v.w; 32.279 + return v; 32.280 +} 32.281 + 32.282 +static inline vec4_t v4_mul(vec4_t v1, vec4_t v2) 32.283 +{ 32.284 + v1.x *= v2.x; 32.285 + v1.y *= v2.y; 32.286 + v1.z *= v2.z; 32.287 + v1.w *= v2.w; 32.288 + return v1; 32.289 +} 32.290 + 32.291 +static inline vec4_t v4_scale(vec4_t v, scalar_t s) 32.292 +{ 32.293 + v.x *= s; 32.294 + v.y *= s; 32.295 + v.z *= s; 32.296 + v.w *= s; 32.297 + return v; 32.298 +} 32.299 + 32.300 +static inline scalar_t v4_dot(vec4_t v1, vec4_t v2) 32.301 +{ 32.302 + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; 32.303 +} 32.304 + 32.305 +static inline scalar_t v4_length(vec4_t v) 32.306 +{ 32.307 + return sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); 32.308 +} 32.309 + 32.310 +static inline scalar_t v4_length_sq(vec4_t v) 32.311 +{ 32.312 + return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w; 32.313 +} 32.314 + 32.315 +static inline vec4_t v4_normalize(vec4_t v) 32.316 +{ 32.317 + scalar_t len = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); 32.318 + v.x /= len; 32.319 + v.y /= len; 32.320 + v.z /= len; 32.321 + v.w /= len; 32.322 + return v; 32.323 +} 32.324 + 32.325 +static inline vec4_t v4_transform(vec4_t v, mat4_t m) 32.326 +{ 32.327 + vec4_t res; 32.328 + res.x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w; 32.329 + res.y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w; 32.330 + res.z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w; 32.331 + res.w = m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w; 32.332 + return res; 32.333 +} 32.334 + 32.335 +#ifdef __cplusplus 32.336 +} /* extern "C" */ 32.337 + 32.338 + 32.339 +/* --------------- C++ part -------------- */ 32.340 + 32.341 +inline scalar_t &Vector2::operator [](int elem) 32.342 +{ 32.343 + return elem ? y : x; 32.344 +} 32.345 + 32.346 +inline const scalar_t &Vector2::operator [](int elem) const 32.347 +{ 32.348 + return elem ? y : x; 32.349 +} 32.350 + 32.351 +inline Vector2 operator -(const Vector2 &vec) 32.352 +{ 32.353 + return Vector2(-vec.x, -vec.y); 32.354 +} 32.355 + 32.356 +inline scalar_t dot_product(const Vector2 &v1, const Vector2 &v2) 32.357 +{ 32.358 + return v1.x * v2.x + v1.y * v2.y; 32.359 +} 32.360 + 32.361 +inline Vector2 operator +(const Vector2 &v1, const Vector2 &v2) 32.362 +{ 32.363 + return Vector2(v1.x + v2.x, v1.y + v2.y); 32.364 +} 32.365 + 32.366 +inline Vector2 operator -(const Vector2 &v1, const Vector2 &v2) 32.367 +{ 32.368 + return Vector2(v1.x - v2.x, v1.y - v2.y); 32.369 +} 32.370 + 32.371 +inline Vector2 operator *(const Vector2 &v1, const Vector2 &v2) 32.372 +{ 32.373 + return Vector2(v1.x * v2.x, v1.y * v2.y); 32.374 +} 32.375 + 32.376 +inline Vector2 operator /(const Vector2 &v1, const Vector2 &v2) 32.377 +{ 32.378 + return Vector2(v1.x / v2.x, v1.y / v2.y); 32.379 +} 32.380 + 32.381 +inline bool operator ==(const Vector2 &v1, const Vector2 &v2) 32.382 +{ 32.383 + return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.x) < XSMALL_NUMBER); 32.384 +} 32.385 + 32.386 +inline void operator +=(Vector2 &v1, const Vector2 &v2) 32.387 +{ 32.388 + v1.x += v2.x; 32.389 + v1.y += v2.y; 32.390 +} 32.391 + 32.392 +inline void operator -=(Vector2 &v1, const Vector2 &v2) 32.393 +{ 32.394 + v1.x -= v2.x; 32.395 + v1.y -= v2.y; 32.396 +} 32.397 + 32.398 +inline void operator *=(Vector2 &v1, const Vector2 &v2) 32.399 +{ 32.400 + v1.x *= v2.x; 32.401 + v1.y *= v2.y; 32.402 +} 32.403 + 32.404 +inline void operator /=(Vector2 &v1, const Vector2 &v2) 32.405 +{ 32.406 + v1.x /= v2.x; 32.407 + v1.y /= v2.y; 32.408 +} 32.409 + 32.410 +inline Vector2 operator +(const Vector2 &vec, scalar_t scalar) 32.411 +{ 32.412 + return Vector2(vec.x + scalar, vec.y + scalar); 32.413 +} 32.414 + 32.415 +inline Vector2 operator +(scalar_t scalar, const Vector2 &vec) 32.416 +{ 32.417 + return Vector2(vec.x + scalar, vec.y + scalar); 32.418 +} 32.419 + 32.420 +inline Vector2 operator -(const Vector2 &vec, scalar_t scalar) 32.421 +{ 32.422 + return Vector2(vec.x - scalar, vec.y - scalar); 32.423 +} 32.424 + 32.425 +inline Vector2 operator *(const Vector2 &vec, scalar_t scalar) 32.426 +{ 32.427 + return Vector2(vec.x * scalar, vec.y * scalar); 32.428 +} 32.429 + 32.430 +inline Vector2 operator *(scalar_t scalar, const Vector2 &vec) 32.431 +{ 32.432 + return Vector2(vec.x * scalar, vec.y * scalar); 32.433 +} 32.434 + 32.435 +inline Vector2 operator /(const Vector2 &vec, scalar_t scalar) 32.436 +{ 32.437 + return Vector2(vec.x / scalar, vec.y / scalar); 32.438 +} 32.439 + 32.440 +inline void operator +=(Vector2 &vec, scalar_t scalar) 32.441 +{ 32.442 + vec.x += scalar; 32.443 + vec.y += scalar; 32.444 +} 32.445 + 32.446 +inline void operator -=(Vector2 &vec, scalar_t scalar) 32.447 +{ 32.448 + vec.x -= scalar; 32.449 + vec.y -= scalar; 32.450 +} 32.451 + 32.452 +inline void operator *=(Vector2 &vec, scalar_t scalar) 32.453 +{ 32.454 + vec.x *= scalar; 32.455 + vec.y *= scalar; 32.456 +} 32.457 + 32.458 +inline void operator /=(Vector2 &vec, scalar_t scalar) 32.459 +{ 32.460 + vec.x /= scalar; 32.461 + vec.y /= scalar; 32.462 +} 32.463 + 32.464 +inline scalar_t Vector2::length() const 32.465 +{ 32.466 + return sqrt(x*x + y*y); 32.467 +} 32.468 + 32.469 +inline scalar_t Vector2::length_sq() const 32.470 +{ 32.471 + return x*x + y*y; 32.472 +} 32.473 + 32.474 +inline Vector2 lerp(const Vector2 &a, const Vector2 &b, scalar_t t) 32.475 +{ 32.476 + return a + (b - a) * t; 32.477 +} 32.478 + 32.479 +inline Vector2 catmull_rom_spline(const Vector2 &v0, const Vector2 &v1, 32.480 + const Vector2 &v2, const Vector2 &v3, scalar_t t) 32.481 +{ 32.482 + scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); 32.483 + scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); 32.484 + return Vector2(x, y); 32.485 +} 32.486 + 32.487 +inline Vector2 bspline(const Vector2 &v0, const Vector2 &v1, 32.488 + const Vector2 &v2, const Vector2 &v3, scalar_t t) 32.489 +{ 32.490 + scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t); 32.491 + scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t); 32.492 + return Vector2(x, y); 32.493 +} 32.494 + 32.495 + 32.496 +/* ------------- Vector3 -------------- */ 32.497 + 32.498 +inline scalar_t &Vector3::operator [](int elem) { 32.499 + return elem ? (elem == 1 ? y : z) : x; 32.500 +} 32.501 + 32.502 +inline const scalar_t &Vector3::operator [](int elem) const { 32.503 + return elem ? (elem == 1 ? y : z) : x; 32.504 +} 32.505 + 32.506 +/* unary operations */ 32.507 +inline Vector3 operator -(const Vector3 &vec) { 32.508 + return Vector3(-vec.x, -vec.y, -vec.z); 32.509 +} 32.510 + 32.511 +/* binary vector (op) vector operations */ 32.512 +inline scalar_t dot_product(const Vector3 &v1, const Vector3 &v2) { 32.513 + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; 32.514 +} 32.515 + 32.516 +inline Vector3 cross_product(const Vector3 &v1, const Vector3 &v2) { 32.517 + return Vector3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); 32.518 +} 32.519 + 32.520 + 32.521 +inline Vector3 operator +(const Vector3 &v1, const Vector3 &v2) { 32.522 + return Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); 32.523 +} 32.524 + 32.525 +inline Vector3 operator -(const Vector3 &v1, const Vector3 &v2) { 32.526 + return Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); 32.527 +} 32.528 + 32.529 +inline Vector3 operator *(const Vector3 &v1, const Vector3 &v2) { 32.530 + return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); 32.531 +} 32.532 + 32.533 +inline Vector3 operator /(const Vector3 &v1, const Vector3 &v2) { 32.534 + return Vector3(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z); 32.535 +} 32.536 + 32.537 +inline bool operator ==(const Vector3 &v1, const Vector3 &v2) { 32.538 + return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && (fabs(v1.y - v2.y) < XSMALL_NUMBER) && (fabs(v1.z - v2.z) < XSMALL_NUMBER); 32.539 +} 32.540 + 32.541 +inline void operator +=(Vector3 &v1, const Vector3 &v2) { 32.542 + v1.x += v2.x; 32.543 + v1.y += v2.y; 32.544 + v1.z += v2.z; 32.545 +} 32.546 + 32.547 +inline void operator -=(Vector3 &v1, const Vector3 &v2) { 32.548 + v1.x -= v2.x; 32.549 + v1.y -= v2.y; 32.550 + v1.z -= v2.z; 32.551 +} 32.552 + 32.553 +inline void operator *=(Vector3 &v1, const Vector3 &v2) { 32.554 + v1.x *= v2.x; 32.555 + v1.y *= v2.y; 32.556 + v1.z *= v2.z; 32.557 +} 32.558 + 32.559 +inline void operator /=(Vector3 &v1, const Vector3 &v2) { 32.560 + v1.x /= v2.x; 32.561 + v1.y /= v2.y; 32.562 + v1.z /= v2.z; 32.563 +} 32.564 +/* binary vector (op) scalar and scalar (op) vector operations */ 32.565 +inline Vector3 operator +(const Vector3 &vec, scalar_t scalar) { 32.566 + return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar); 32.567 +} 32.568 + 32.569 +inline Vector3 operator +(scalar_t scalar, const Vector3 &vec) { 32.570 + return Vector3(vec.x + scalar, vec.y + scalar, vec.z + scalar); 32.571 +} 32.572 + 32.573 +inline Vector3 operator -(const Vector3 &vec, scalar_t scalar) { 32.574 + return Vector3(vec.x - scalar, vec.y - scalar, vec.z - scalar); 32.575 +} 32.576 + 32.577 +inline Vector3 operator *(const Vector3 &vec, scalar_t scalar) { 32.578 + return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar); 32.579 +} 32.580 + 32.581 +inline Vector3 operator *(scalar_t scalar, const Vector3 &vec) { 32.582 + return Vector3(vec.x * scalar, vec.y * scalar, vec.z * scalar); 32.583 +} 32.584 + 32.585 +inline Vector3 operator /(const Vector3 &vec, scalar_t scalar) { 32.586 + return Vector3(vec.x / scalar, vec.y / scalar, vec.z / scalar); 32.587 +} 32.588 + 32.589 +inline void operator +=(Vector3 &vec, scalar_t scalar) { 32.590 + vec.x += scalar; 32.591 + vec.y += scalar; 32.592 + vec.z += scalar; 32.593 +} 32.594 + 32.595 +inline void operator -=(Vector3 &vec, scalar_t scalar) { 32.596 + vec.x -= scalar; 32.597 + vec.y -= scalar; 32.598 + vec.z -= scalar; 32.599 +} 32.600 + 32.601 +inline void operator *=(Vector3 &vec, scalar_t scalar) { 32.602 + vec.x *= scalar; 32.603 + vec.y *= scalar; 32.604 + vec.z *= scalar; 32.605 +} 32.606 + 32.607 +inline void operator /=(Vector3 &vec, scalar_t scalar) { 32.608 + vec.x /= scalar; 32.609 + vec.y /= scalar; 32.610 + vec.z /= scalar; 32.611 +} 32.612 + 32.613 +inline scalar_t Vector3::length() const { 32.614 + return sqrt(x*x + y*y + z*z); 32.615 +} 32.616 +inline scalar_t Vector3::length_sq() const { 32.617 + return x*x + y*y + z*z; 32.618 +} 32.619 + 32.620 +inline Vector3 lerp(const Vector3 &a, const Vector3 &b, scalar_t t) { 32.621 + return a + (b - a) * t; 32.622 +} 32.623 + 32.624 +inline Vector3 catmull_rom_spline(const Vector3 &v0, const Vector3 &v1, 32.625 + const Vector3 &v2, const Vector3 &v3, scalar_t t) 32.626 +{ 32.627 + scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); 32.628 + scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); 32.629 + scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t); 32.630 + return Vector3(x, y, z); 32.631 +} 32.632 + 32.633 +inline Vector3 bspline(const Vector3 &v0, const Vector3 &v1, 32.634 + const Vector3 &v2, const Vector3 &v3, scalar_t t) 32.635 +{ 32.636 + scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t); 32.637 + scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t); 32.638 + scalar_t z = bspline(v0.z, v1.z, v2.z, v3.z, t); 32.639 + return Vector3(x, y, z); 32.640 +} 32.641 + 32.642 +/* ----------- Vector4 ----------------- */ 32.643 + 32.644 +inline scalar_t &Vector4::operator [](int elem) { 32.645 + return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x; 32.646 +} 32.647 + 32.648 +inline const scalar_t &Vector4::operator [](int elem) const { 32.649 + return elem ? (elem == 1 ? y : (elem == 2 ? z : w)) : x; 32.650 +} 32.651 + 32.652 +inline Vector4 operator -(const Vector4 &vec) { 32.653 + return Vector4(-vec.x, -vec.y, -vec.z, -vec.w); 32.654 +} 32.655 + 32.656 +inline scalar_t dot_product(const Vector4 &v1, const Vector4 &v2) { 32.657 + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; 32.658 +} 32.659 + 32.660 +inline Vector4 cross_product(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) { 32.661 + scalar_t a, b, c, d, e, f; /* Intermediate Values */ 32.662 + Vector4 result; 32.663 + 32.664 + /* Calculate intermediate values. */ 32.665 + a = (v2.x * v3.y) - (v2.y * v3.x); 32.666 + b = (v2.x * v3.z) - (v2.z * v3.x); 32.667 + c = (v2.x * v3.w) - (v2.w * v3.x); 32.668 + d = (v2.y * v3.z) - (v2.z * v3.y); 32.669 + e = (v2.y * v3.w) - (v2.w * v3.y); 32.670 + f = (v2.z * v3.w) - (v2.w * v3.z); 32.671 + 32.672 + /* Calculate the result-vector components. */ 32.673 + result.x = (v1.y * f) - (v1.z * e) + (v1.w * d); 32.674 + result.y = - (v1.x * f) + (v1.z * c) - (v1.w * b); 32.675 + result.z = (v1.x * e) - (v1.y * c) + (v1.w * a); 32.676 + result.w = - (v1.x * d) + (v1.y * b) - (v1.z * a); 32.677 + return result; 32.678 +} 32.679 + 32.680 +inline Vector4 operator +(const Vector4 &v1, const Vector4 &v2) { 32.681 + return Vector4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w); 32.682 +} 32.683 + 32.684 +inline Vector4 operator -(const Vector4 &v1, const Vector4 &v2) { 32.685 + return Vector4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w); 32.686 +} 32.687 + 32.688 +inline Vector4 operator *(const Vector4 &v1, const Vector4 &v2) { 32.689 + return Vector4(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w); 32.690 +} 32.691 + 32.692 +inline Vector4 operator /(const Vector4 &v1, const Vector4 &v2) { 32.693 + return Vector4(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w); 32.694 +} 32.695 + 32.696 +inline bool operator ==(const Vector4 &v1, const Vector4 &v2) { 32.697 + return (fabs(v1.x - v2.x) < XSMALL_NUMBER) && 32.698 + (fabs(v1.y - v2.y) < XSMALL_NUMBER) && 32.699 + (fabs(v1.z - v2.z) < XSMALL_NUMBER) && 32.700 + (fabs(v1.w - v2.w) < XSMALL_NUMBER); 32.701 +} 32.702 + 32.703 +inline void operator +=(Vector4 &v1, const Vector4 &v2) { 32.704 + v1.x += v2.x; 32.705 + v1.y += v2.y; 32.706 + v1.z += v2.z; 32.707 + v1.w += v2.w; 32.708 +} 32.709 + 32.710 +inline void operator -=(Vector4 &v1, const Vector4 &v2) { 32.711 + v1.x -= v2.x; 32.712 + v1.y -= v2.y; 32.713 + v1.z -= v2.z; 32.714 + v1.w -= v2.w; 32.715 +} 32.716 + 32.717 +inline void operator *=(Vector4 &v1, const Vector4 &v2) { 32.718 + v1.x *= v2.x; 32.719 + v1.y *= v2.y; 32.720 + v1.z *= v2.z; 32.721 + v1.w *= v2.w; 32.722 +} 32.723 + 32.724 +inline void operator /=(Vector4 &v1, const Vector4 &v2) { 32.725 + v1.x /= v2.x; 32.726 + v1.y /= v2.y; 32.727 + v1.z /= v2.z; 32.728 + v1.w /= v2.w; 32.729 +} 32.730 + 32.731 +/* binary vector (op) scalar and scalar (op) vector operations */ 32.732 +inline Vector4 operator +(const Vector4 &vec, scalar_t scalar) { 32.733 + return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar); 32.734 +} 32.735 + 32.736 +inline Vector4 operator +(scalar_t scalar, const Vector4 &vec) { 32.737 + return Vector4(vec.x + scalar, vec.y + scalar, vec.z + scalar, vec.w + scalar); 32.738 +} 32.739 + 32.740 +inline Vector4 operator -(const Vector4 &vec, scalar_t scalar) { 32.741 + return Vector4(vec.x - scalar, vec.y - scalar, vec.z - scalar, vec.w - scalar); 32.742 +} 32.743 + 32.744 +inline Vector4 operator *(const Vector4 &vec, scalar_t scalar) { 32.745 + return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar); 32.746 +} 32.747 + 32.748 +inline Vector4 operator *(scalar_t scalar, const Vector4 &vec) { 32.749 + return Vector4(vec.x * scalar, vec.y * scalar, vec.z * scalar, vec.w * scalar); 32.750 +} 32.751 + 32.752 +inline Vector4 operator /(const Vector4 &vec, scalar_t scalar) { 32.753 + return Vector4(vec.x / scalar, vec.y / scalar, vec.z / scalar, vec.w / scalar); 32.754 +} 32.755 + 32.756 +inline void operator +=(Vector4 &vec, scalar_t scalar) { 32.757 + vec.x += scalar; 32.758 + vec.y += scalar; 32.759 + vec.z += scalar; 32.760 + vec.w += scalar; 32.761 +} 32.762 + 32.763 +inline void operator -=(Vector4 &vec, scalar_t scalar) { 32.764 + vec.x -= scalar; 32.765 + vec.y -= scalar; 32.766 + vec.z -= scalar; 32.767 + vec.w -= scalar; 32.768 +} 32.769 + 32.770 +inline void operator *=(Vector4 &vec, scalar_t scalar) { 32.771 + vec.x *= scalar; 32.772 + vec.y *= scalar; 32.773 + vec.z *= scalar; 32.774 + vec.w *= scalar; 32.775 +} 32.776 + 32.777 +inline void operator /=(Vector4 &vec, scalar_t scalar) { 32.778 + vec.x /= scalar; 32.779 + vec.y /= scalar; 32.780 + vec.z /= scalar; 32.781 + vec.w /= scalar; 32.782 +} 32.783 + 32.784 +inline scalar_t Vector4::length() const { 32.785 + return sqrt(x*x + y*y + z*z + w*w); 32.786 +} 32.787 +inline scalar_t Vector4::length_sq() const { 32.788 + return x*x + y*y + z*z + w*w; 32.789 +} 32.790 + 32.791 +inline Vector4 lerp(const Vector4 &v0, const Vector4 &v1, scalar_t t) 32.792 +{ 32.793 + return v0 + (v1 - v0) * t; 32.794 +} 32.795 + 32.796 +inline Vector4 catmull_rom_spline(const Vector4 &v0, const Vector4 &v1, 32.797 + const Vector4 &v2, const Vector4 &v3, scalar_t t) 32.798 +{ 32.799 + scalar_t x = spline(v0.x, v1.x, v2.x, v3.x, t); 32.800 + scalar_t y = spline(v0.y, v1.y, v2.y, v3.y, t); 32.801 + scalar_t z = spline(v0.z, v1.z, v2.z, v3.z, t); 32.802 + scalar_t w = spline(v0.w, v1.w, v2.w, v3.w, t); 32.803 + return Vector4(x, y, z, w); 32.804 +} 32.805 + 32.806 +inline Vector4 bspline(const Vector4 &v0, const Vector4 &v1, 32.807 + const Vector4 &v2, const Vector4 &v3, scalar_t t) 32.808 +{ 32.809 + scalar_t x = bspline(v0.x, v1.x, v2.x, v3.x, t); 32.810 + scalar_t y = bspline(v0.y, v1.y, v2.y, v3.y, t); 32.811 + scalar_t z = bspline(v0.z, v1.z, v2.z, v3.z, t); 32.812 + scalar_t w = bspline(v0.w, v1.w, v2.w, v3.w, t); 32.813 + return Vector4(x, y, z, w); 32.814 +} 32.815 +#endif /* __cplusplus */
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/libs/vmath/vmath.c Sun May 31 00:40:26 2015 +0300 33.3 @@ -0,0 +1,396 @@ 33.4 +/* 33.5 +libvmath - a vector math library 33.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 33.7 + 33.8 +This program is free software: you can redistribute it and/or modify 33.9 +it under the terms of the GNU Lesser General Public License as published 33.10 +by the Free Software Foundation, either version 3 of the License, or 33.11 +(at your option) any later version. 33.12 + 33.13 +This program is distributed in the hope that it will be useful, 33.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 33.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33.16 +GNU Lesser General Public License for more details. 33.17 + 33.18 +You should have received a copy of the GNU Lesser General Public License 33.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 33.20 +*/ 33.21 +#include <stdlib.h> 33.22 +#include <math.h> 33.23 +#include "vmath.h" 33.24 + 33.25 +#if defined(__APPLE__) && !defined(TARGET_IPHONE) 33.26 +#include <xmmintrin.h> 33.27 + 33.28 +void enable_fpexcept(void) 33.29 +{ 33.30 + unsigned int bits; 33.31 + bits = _MM_MASK_INVALID | _MM_MASK_DIV_ZERO | _MM_MASK_OVERFLOW | _MM_MASK_UNDERFLOW; 33.32 + _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~bits); 33.33 +} 33.34 + 33.35 +void disable_fpexcept(void) 33.36 +{ 33.37 + unsigned int bits; 33.38 + bits = _MM_MASK_INVALID | _MM_MASK_DIV_ZERO | _MM_MASK_OVERFLOW | _MM_MASK_UNDERFLOW; 33.39 + _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() | bits); 33.40 +} 33.41 + 33.42 +#elif defined(__GNUC__) && !defined(TARGET_IPHONE) && !defined(__MINGW32__) 33.43 +#define __USE_GNU 33.44 +#include <fenv.h> 33.45 + 33.46 +void enable_fpexcept(void) 33.47 +{ 33.48 + feenableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW); 33.49 +} 33.50 + 33.51 +void disable_fpexcept(void) 33.52 +{ 33.53 + fedisableexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW); 33.54 +} 33.55 + 33.56 +#elif defined(_MSC_VER) || defined(__MINGW32__) 33.57 +#include <float.h> 33.58 + 33.59 +#if defined(__MINGW32__) && !defined(_EM_OVERFLOW) 33.60 +/* if gcc's float.h gets precedence, the mingw MSVC includes won't be declared */ 33.61 +#define _MCW_EM 0x8001f 33.62 +#define _EM_INVALID 0x10 33.63 +#define _EM_ZERODIVIDE 0x08 33.64 +#define _EM_OVERFLOW 0x04 33.65 +unsigned int __cdecl _clearfp(void); 33.66 +unsigned int __cdecl _controlfp(unsigned int, unsigned int); 33.67 +#endif 33.68 + 33.69 +void enable_fpexcept(void) 33.70 +{ 33.71 + _clearfp(); 33.72 + _controlfp(_controlfp(0, 0) & ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW), _MCW_EM); 33.73 +} 33.74 + 33.75 +void disable_fpexcept(void) 33.76 +{ 33.77 + _clearfp(); 33.78 + _controlfp(_controlfp(0, 0) | (_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW), _MCW_EM); 33.79 +} 33.80 +#else 33.81 +void enable_fpexcept(void) {} 33.82 +void disable_fpexcept(void) {} 33.83 +#endif 33.84 + 33.85 + 33.86 +/** Numerical calculation of integrals using simpson's rule */ 33.87 +scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples) 33.88 +{ 33.89 + int i; 33.90 + scalar_t h = (high - low) / (scalar_t)samples; 33.91 + scalar_t sum = 0.0; 33.92 + 33.93 + for(i=0; i<samples+1; i++) { 33.94 + scalar_t y = f((scalar_t)i * h + low); 33.95 + sum += ((!i || i == samples) ? y : ((i % 2) ? 4.0 * y : 2.0 * y)) * (h / 3.0); 33.96 + } 33.97 + return sum; 33.98 +} 33.99 + 33.100 +/** Gaussuan function */ 33.101 +scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev) 33.102 +{ 33.103 + scalar_t exponent = -SQ(x - mean) / (2.0 * SQ(sdev)); 33.104 + return 1.0 - -pow(M_E, exponent) / (sdev * sqrt(TWO_PI)); 33.105 +} 33.106 + 33.107 + 33.108 +/** b-spline approximation */ 33.109 +scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t) 33.110 +{ 33.111 + vec4_t tmp; 33.112 + scalar_t tsq = t * t; 33.113 + 33.114 + static mat4_t bspline_mat = { 33.115 + {-1, 3, -3, 1}, 33.116 + {3, -6, 3, 0}, 33.117 + {-3, 0, 3, 0}, 33.118 + {1, 4, 1, 0} 33.119 + }; 33.120 + 33.121 + tmp = v4_scale(v4_transform(v4_cons(a, b, c, d), bspline_mat), 1.0 / 6.0); 33.122 + return v4_dot(v4_cons(tsq * t, tsq, t, 1.0), tmp); 33.123 +} 33.124 + 33.125 +/** Catmull-rom spline interpolation */ 33.126 +scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t) 33.127 +{ 33.128 + vec4_t tmp; 33.129 + scalar_t tsq = t * t; 33.130 + 33.131 + static mat4_t crspline_mat = { 33.132 + {-1, 3, -3, 1}, 33.133 + {2, -5, 4, -1}, 33.134 + {-1, 0, 1, 0}, 33.135 + {0, 2, 0, 0} 33.136 + }; 33.137 + 33.138 + tmp = v4_scale(v4_transform(v4_cons(a, b, c, d), crspline_mat), 0.5); 33.139 + return v4_dot(v4_cons(tsq * t, tsq, t, 1.0), tmp); 33.140 +} 33.141 + 33.142 +/** Bezier interpolation */ 33.143 +scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t) 33.144 +{ 33.145 + scalar_t omt, omt3, t3, f; 33.146 + t3 = t * t * t; 33.147 + omt = 1.0f - t; 33.148 + omt3 = omt * omt * omt; 33.149 + f = 3 * t * omt; 33.150 + 33.151 + return (a * omt3) + (b * f * omt) + (c * f * t) + (d * t3); 33.152 +} 33.153 + 33.154 +/* ---- Ken Perlin's implementation of noise ---- */ 33.155 + 33.156 +#define B 0x100 33.157 +#define BM 0xff 33.158 +#define N 0x1000 33.159 +#define NP 12 /* 2^N */ 33.160 +#define NM 0xfff 33.161 + 33.162 +#define s_curve(t) (t * t * (3.0f - 2.0f * t)) 33.163 + 33.164 +#define setup(elem, b0, b1, r0, r1) \ 33.165 + do { \ 33.166 + scalar_t t = elem + N; \ 33.167 + b0 = ((int)t) & BM; \ 33.168 + b1 = (b0 + 1) & BM; \ 33.169 + r0 = t - (int)t; \ 33.170 + r1 = r0 - 1.0f; \ 33.171 + } while(0) 33.172 + 33.173 + 33.174 +static int perm[B + B + 2]; /* permuted index from g_n onto themselves */ 33.175 +static vec3_t grad3[B + B + 2]; /* 3D random gradients */ 33.176 +static vec2_t grad2[B + B + 2]; /* 2D random gradients */ 33.177 +static scalar_t grad1[B + B + 2]; /* 1D random ... slopes */ 33.178 +static int tables_valid; 33.179 + 33.180 +static void init_noise() 33.181 +{ 33.182 + int i; 33.183 + 33.184 + /* calculate random gradients */ 33.185 + for(i=0; i<B; i++) { 33.186 + perm[i] = i; /* .. and initialize permutation mapping to identity */ 33.187 + 33.188 + grad1[i] = (scalar_t)((rand() % (B + B)) - B) / B; 33.189 + 33.190 + grad2[i].x = (scalar_t)((rand() % (B + B)) - B) / B; 33.191 + grad2[i].y = (scalar_t)((rand() % (B + B)) - B) / B; 33.192 + grad2[i] = v2_normalize(grad2[i]); 33.193 + 33.194 + grad3[i].x = (scalar_t)((rand() % (B + B)) - B) / B; 33.195 + grad3[i].y = (scalar_t)((rand() % (B + B)) - B) / B; 33.196 + grad3[i].z = (scalar_t)((rand() % (B + B)) - B) / B; 33.197 + grad3[i] = v3_normalize(grad3[i]); 33.198 + } 33.199 + 33.200 + /* permute indices by swapping them randomly */ 33.201 + for(i=0; i<B; i++) { 33.202 + int rand_idx = rand() % B; 33.203 + 33.204 + int tmp = perm[i]; 33.205 + perm[i] = perm[rand_idx]; 33.206 + perm[rand_idx] = tmp; 33.207 + } 33.208 + 33.209 + /* fill up the rest of the arrays by duplicating the existing gradients */ 33.210 + /* and permutations */ 33.211 + for(i=0; i<B+2; i++) { 33.212 + perm[B + i] = perm[i]; 33.213 + grad1[B + i] = grad1[i]; 33.214 + grad2[B + i] = grad2[i]; 33.215 + grad3[B + i] = grad3[i]; 33.216 + } 33.217 +} 33.218 + 33.219 +scalar_t noise1(scalar_t x) 33.220 +{ 33.221 + int bx0, bx1; 33.222 + scalar_t rx0, rx1, sx, u, v; 33.223 + 33.224 + if(!tables_valid) { 33.225 + init_noise(); 33.226 + tables_valid = 1; 33.227 + } 33.228 + 33.229 + setup(x, bx0, bx1, rx0, rx1); 33.230 + sx = s_curve(rx0); 33.231 + u = rx0 * grad1[perm[bx0]]; 33.232 + v = rx1 * grad1[perm[bx1]]; 33.233 + 33.234 + return lerp(u, v, sx); 33.235 +} 33.236 + 33.237 +scalar_t noise2(scalar_t x, scalar_t y) 33.238 +{ 33.239 + int i, j, b00, b10, b01, b11; 33.240 + int bx0, bx1, by0, by1; 33.241 + scalar_t rx0, rx1, ry0, ry1; 33.242 + scalar_t sx, sy, u, v, a, b; 33.243 + 33.244 + if(!tables_valid) { 33.245 + init_noise(); 33.246 + tables_valid = 1; 33.247 + } 33.248 + 33.249 + setup(x, bx0, bx1, rx0, rx1); 33.250 + setup(y, by0, by1, ry0, ry1); 33.251 + 33.252 + i = perm[bx0]; 33.253 + j = perm[bx1]; 33.254 + 33.255 + b00 = perm[i + by0]; 33.256 + b10 = perm[j + by0]; 33.257 + b01 = perm[i + by1]; 33.258 + b11 = perm[j + by1]; 33.259 + 33.260 + /* calculate hermite inteprolating factors */ 33.261 + sx = s_curve(rx0); 33.262 + sy = s_curve(ry0); 33.263 + 33.264 + /* interpolate along the left edge */ 33.265 + u = v2_dot(grad2[b00], v2_cons(rx0, ry0)); 33.266 + v = v2_dot(grad2[b10], v2_cons(rx1, ry0)); 33.267 + a = lerp(u, v, sx); 33.268 + 33.269 + /* interpolate along the right edge */ 33.270 + u = v2_dot(grad2[b01], v2_cons(rx0, ry1)); 33.271 + v = v2_dot(grad2[b11], v2_cons(rx1, ry1)); 33.272 + b = lerp(u, v, sx); 33.273 + 33.274 + /* interpolate between them */ 33.275 + return lerp(a, b, sy); 33.276 +} 33.277 + 33.278 +scalar_t noise3(scalar_t x, scalar_t y, scalar_t z) 33.279 +{ 33.280 + int i, j; 33.281 + int bx0, bx1, by0, by1, bz0, bz1; 33.282 + int b00, b10, b01, b11; 33.283 + scalar_t rx0, rx1, ry0, ry1, rz0, rz1; 33.284 + scalar_t sx, sy, sz; 33.285 + scalar_t u, v, a, b, c, d; 33.286 + 33.287 + if(!tables_valid) { 33.288 + init_noise(); 33.289 + tables_valid = 1; 33.290 + } 33.291 + 33.292 + setup(x, bx0, bx1, rx0, rx1); 33.293 + setup(y, by0, by1, ry0, ry1); 33.294 + setup(z, bz0, bz1, rz0, rz1); 33.295 + 33.296 + i = perm[bx0]; 33.297 + j = perm[bx1]; 33.298 + 33.299 + b00 = perm[i + by0]; 33.300 + b10 = perm[j + by0]; 33.301 + b01 = perm[i + by1]; 33.302 + b11 = perm[j + by1]; 33.303 + 33.304 + /* calculate hermite interpolating factors */ 33.305 + sx = s_curve(rx0); 33.306 + sy = s_curve(ry0); 33.307 + sz = s_curve(rz0); 33.308 + 33.309 + /* interpolate along the top slice of the cell */ 33.310 + u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz0)); 33.311 + v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz0)); 33.312 + a = lerp(u, v, sx); 33.313 + 33.314 + u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz0)); 33.315 + v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz0)); 33.316 + b = lerp(u, v, sx); 33.317 + 33.318 + c = lerp(a, b, sy); 33.319 + 33.320 + /* interpolate along the bottom slice of the cell */ 33.321 + u = v3_dot(grad3[b00 + bz0], v3_cons(rx0, ry0, rz1)); 33.322 + v = v3_dot(grad3[b10 + bz0], v3_cons(rx1, ry0, rz1)); 33.323 + a = lerp(u, v, sx); 33.324 + 33.325 + u = v3_dot(grad3[b01 + bz0], v3_cons(rx0, ry1, rz1)); 33.326 + v = v3_dot(grad3[b11 + bz0], v3_cons(rx1, ry1, rz1)); 33.327 + b = lerp(u, v, sx); 33.328 + 33.329 + d = lerp(a, b, sy); 33.330 + 33.331 + /* interpolate between slices */ 33.332 + return lerp(c, d, sz); 33.333 +} 33.334 + 33.335 +scalar_t fbm1(scalar_t x, int octaves) 33.336 +{ 33.337 + int i; 33.338 + scalar_t res = 0.0f, freq = 1.0f; 33.339 + for(i=0; i<octaves; i++) { 33.340 + res += noise1(x * freq) / freq; 33.341 + freq *= 2.0f; 33.342 + } 33.343 + return res; 33.344 +} 33.345 + 33.346 +scalar_t fbm2(scalar_t x, scalar_t y, int octaves) 33.347 +{ 33.348 + int i; 33.349 + scalar_t res = 0.0f, freq = 1.0f; 33.350 + for(i=0; i<octaves; i++) { 33.351 + res += noise2(x * freq, y * freq) / freq; 33.352 + freq *= 2.0f; 33.353 + } 33.354 + return res; 33.355 +} 33.356 + 33.357 +scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves) 33.358 +{ 33.359 + int i; 33.360 + scalar_t res = 0.0f, freq = 1.0f; 33.361 + for(i=0; i<octaves; i++) { 33.362 + res += noise3(x * freq, y * freq, z * freq) / freq; 33.363 + freq *= 2.0f; 33.364 + } 33.365 + return res; 33.366 +} 33.367 + 33.368 +scalar_t turbulence1(scalar_t x, int octaves) 33.369 +{ 33.370 + int i; 33.371 + scalar_t res = 0.0f, freq = 1.0f; 33.372 + for(i=0; i<octaves; i++) { 33.373 + res += fabs(noise1(x * freq) / freq); 33.374 + freq *= 2.0f; 33.375 + } 33.376 + return res; 33.377 +} 33.378 + 33.379 +scalar_t turbulence2(scalar_t x, scalar_t y, int octaves) 33.380 +{ 33.381 + int i; 33.382 + scalar_t res = 0.0f, freq = 1.0f; 33.383 + for(i=0; i<octaves; i++) { 33.384 + res += fabs(noise2(x * freq, y * freq) / freq); 33.385 + freq *= 2.0f; 33.386 + } 33.387 + return res; 33.388 +} 33.389 + 33.390 +scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves) 33.391 +{ 33.392 + int i; 33.393 + scalar_t res = 0.0f, freq = 1.0f; 33.394 + for(i=0; i<octaves; i++) { 33.395 + res += fabs(noise3(x * freq, y * freq, z * freq) / freq); 33.396 + freq *= 2.0f; 33.397 + } 33.398 + return res; 33.399 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/libs/vmath/vmath.h Sun May 31 00:40:26 2015 +0300 34.3 @@ -0,0 +1,97 @@ 34.4 +/* 34.5 +libvmath - a vector math library 34.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 34.7 + 34.8 +This program is free software: you can redistribute it and/or modify 34.9 +it under the terms of the GNU Lesser General Public License as published 34.10 +by the Free Software Foundation, either version 3 of the License, or 34.11 +(at your option) any later version. 34.12 + 34.13 +This program is distributed in the hope that it will be useful, 34.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 34.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34.16 +GNU Lesser General Public License for more details. 34.17 + 34.18 +You should have received a copy of the GNU Lesser General Public License 34.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 34.20 +*/ 34.21 + 34.22 +#ifndef VMATH_H_ 34.23 +#define VMATH_H_ 34.24 + 34.25 +#include <math.h> 34.26 +#include "vmath_types.h" 34.27 + 34.28 +#ifndef M_PI 34.29 +#define M_PI PI 34.30 +#endif 34.31 + 34.32 +#ifndef M_E 34.33 +#define M_E 2.718281828459045 34.34 +#endif 34.35 + 34.36 +#define PI 3.141592653589793 34.37 +#define HALF_PI 1.570796326794897 34.38 +#define QUARTER_PI 0.785398163397448 34.39 +#define TWO_PI 6.283185307179586 34.40 + 34.41 + 34.42 +#define RAD_TO_DEG(a) ((((scalar_t)a) * 360.0) / TWO_PI) 34.43 +#define DEG_TO_RAD(a) (((scalar_t)a) * (PI / 180.0)) 34.44 + 34.45 +#define SQ(x) ((x) * (x)) 34.46 + 34.47 +#define MIN(a, b) ((a) < (b) ? (a) : (b)) 34.48 +#define MAX(a, b) ((a) > (b) ? (a) : (b)) 34.49 + 34.50 +#if (__STDC_VERSION__ < 199901L) && (__cplusplus < 201103L) && !defined(__GNUC__) && (_MSC_VER < 1800) 34.51 +#define round(x) ((x) >= 0 ? (x) + 0.5 : (x) - 0.5) 34.52 +#endif 34.53 + 34.54 +#ifdef __cplusplus 34.55 +extern "C" { 34.56 +#endif /* __cplusplus */ 34.57 + 34.58 +void enable_fpexcept(void); 34.59 +void disable_fpexcept(void); 34.60 + 34.61 +static inline scalar_t smoothstep(float a, float b, float x); 34.62 + 34.63 +static inline scalar_t frand(scalar_t range); 34.64 +static inline vec3_t sphrand(scalar_t rad); 34.65 + 34.66 +scalar_t integral(scalar_t (*f)(scalar_t), scalar_t low, scalar_t high, int samples); 34.67 +scalar_t gaussian(scalar_t x, scalar_t mean, scalar_t sdev); 34.68 + 34.69 +static inline scalar_t lerp(scalar_t a, scalar_t b, scalar_t t); 34.70 + 34.71 +scalar_t bspline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); 34.72 +scalar_t spline(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); 34.73 +scalar_t bezier(scalar_t a, scalar_t b, scalar_t c, scalar_t d, scalar_t t); 34.74 + 34.75 +scalar_t noise1(scalar_t x); 34.76 +scalar_t noise2(scalar_t x, scalar_t y); 34.77 +scalar_t noise3(scalar_t x, scalar_t y, scalar_t z); 34.78 + 34.79 +scalar_t fbm1(scalar_t x, int octaves); 34.80 +scalar_t fbm2(scalar_t x, scalar_t y, int octaves); 34.81 +scalar_t fbm3(scalar_t x, scalar_t y, scalar_t z, int octaves); 34.82 + 34.83 +scalar_t turbulence1(scalar_t x, int octaves); 34.84 +scalar_t turbulence2(scalar_t x, scalar_t y, int octaves); 34.85 +scalar_t turbulence3(scalar_t x, scalar_t y, scalar_t z, int octaves); 34.86 + 34.87 +#ifdef __cplusplus 34.88 +} 34.89 +#endif /* __cplusplus */ 34.90 + 34.91 +#include "vmath.inl" 34.92 + 34.93 +#include "vector.h" 34.94 +#include "matrix.h" 34.95 +#include "quat.h" 34.96 +#include "sphvec.h" 34.97 +#include "ray.h" 34.98 +#include "geom.h" 34.99 + 34.100 +#endif /* VMATH_H_ */
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/libs/vmath/vmath.inl Sun May 31 00:40:26 2015 +0300 35.3 @@ -0,0 +1,56 @@ 35.4 +/* 35.5 +libvmath - a vector math library 35.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 35.7 + 35.8 +This program is free software: you can redistribute it and/or modify 35.9 +it under the terms of the GNU Lesser General Public License as published 35.10 +by the Free Software Foundation, either version 3 of the License, or 35.11 +(at your option) any later version. 35.12 + 35.13 +This program is distributed in the hope that it will be useful, 35.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 35.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35.16 +GNU Lesser General Public License for more details. 35.17 + 35.18 +You should have received a copy of the GNU Lesser General Public License 35.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 35.20 +*/ 35.21 + 35.22 +#include <stdlib.h> 35.23 + 35.24 +static inline scalar_t smoothstep(float a, float b, float x) 35.25 +{ 35.26 + if(x < a) return 0.0; 35.27 + if(x >= b) return 1.0; 35.28 + 35.29 + x = (x - a) / (b - a); 35.30 + return x * x * (3.0 - 2.0 * x); 35.31 +} 35.32 + 35.33 +/** Generates a random number in [0, range) */ 35.34 +static inline scalar_t frand(scalar_t range) 35.35 +{ 35.36 + return range * (scalar_t)rand() / (scalar_t)RAND_MAX; 35.37 +} 35.38 + 35.39 +/** Generates a random vector on the surface of a sphere */ 35.40 +static inline vec3_t sphrand(scalar_t rad) 35.41 +{ 35.42 + scalar_t u = (scalar_t)rand() / RAND_MAX; 35.43 + scalar_t v = (scalar_t)rand() / RAND_MAX; 35.44 + 35.45 + scalar_t theta = 2.0 * M_PI * u; 35.46 + scalar_t phi = acos(2.0 * v - 1.0); 35.47 + 35.48 + vec3_t res; 35.49 + res.x = rad * cos(theta) * sin(phi); 35.50 + res.y = rad * sin(theta) * sin(phi); 35.51 + res.z = rad * cos(phi); 35.52 + return res; 35.53 +} 35.54 + 35.55 +/** linear interpolation */ 35.56 +static inline scalar_t lerp(scalar_t a, scalar_t b, scalar_t t) 35.57 +{ 35.58 + return a + (b - a) * t; 35.59 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/libs/vmath/vmath_config.h Sun May 31 00:40:26 2015 +0300 36.3 @@ -0,0 +1,19 @@ 36.4 +#ifndef VMATH_CONFIG_H_ 36.5 +#define VMATH_CONFIG_H_ 36.6 + 36.7 +#if (__STDC_VERSION__ < 199999) && !defined(__cplusplus) 36.8 +#if defined(__GNUC__) || defined(_MSC_VER) 36.9 +#define inline __inline 36.10 +#else 36.11 +#define inline 36.12 + 36.13 +#ifdef VECTOR_H_ 36.14 +#warning "compiling vector operations without inline, performance might suffer" 36.15 +#endif /* VECTOR_H_ */ 36.16 + 36.17 +#endif /* gcc/msvc */ 36.18 +#endif /* not C99 */ 36.19 + 36.20 +#define SINGLE_PRECISION_MATH 36.21 + 36.22 +#endif /* VMATH_CONFIG_H_ */
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/libs/vmath/vmath_types.h Sun May 31 00:40:26 2015 +0300 37.3 @@ -0,0 +1,58 @@ 37.4 +/* 37.5 +libvmath - a vector math library 37.6 +Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org> 37.7 + 37.8 +This program is free software: you can redistribute it and/or modify 37.9 +it under the terms of the GNU Lesser General Public License as published 37.10 +by the Free Software Foundation, either version 3 of the License, or 37.11 +(at your option) any later version. 37.12 + 37.13 +This program is distributed in the hope that it will be useful, 37.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 37.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37.16 +GNU Lesser General Public License for more details. 37.17 + 37.18 +You should have received a copy of the GNU Lesser General Public License 37.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 37.20 +*/ 37.21 + 37.22 +#ifndef VMATH_TYPES_H_ 37.23 +#define VMATH_TYPES_H_ 37.24 + 37.25 +#include "vmath_config.h" 37.26 + 37.27 +#define SMALL_NUMBER 1.e-4 37.28 +#define XSMALL_NUMBER 1.e-8 37.29 +#define ERROR_MARGIN 1.e-6 37.30 + 37.31 + 37.32 +#ifdef SINGLE_PRECISION_MATH 37.33 +typedef float scalar_t; 37.34 +#else 37.35 +typedef double scalar_t; 37.36 +#endif /* floating point precision */ 37.37 + 37.38 +/* vectors */ 37.39 +typedef struct { scalar_t x, y; } vec2_t; 37.40 +typedef struct { scalar_t x, y, z; } vec3_t; 37.41 +typedef struct { scalar_t x, y, z, w; } vec4_t; 37.42 + 37.43 +/* quaternions */ 37.44 +typedef vec4_t quat_t; 37.45 + 37.46 +/* matrices */ 37.47 +typedef scalar_t mat3_t[3][3]; 37.48 +typedef scalar_t mat4_t[4][4]; 37.49 + 37.50 + 37.51 +#ifdef __cplusplus 37.52 +class Vector2; 37.53 +class Vector3; 37.54 +class Vector4; 37.55 +class Quaternion; 37.56 +class Matrix3x3; 37.57 +class Matrix4x4; 37.58 +class SphVector; 37.59 +#endif /* __cplusplus */ 37.60 + 37.61 +#endif /* VMATH_TYPES_H_ */
38.1 --- a/proj.mk Mon May 25 05:27:26 2015 +0300 38.2 +++ b/proj.mk Sun May 31 00:40:26 2015 +0300 38.3 @@ -1,8 +1,15 @@ 38.4 root ?= $(shell pwd) 38.5 38.6 -src = $(wildcard $(root)/src/*.c) 38.7 +src = $(wildcard $(root)/src/*.c) \ 38.8 + $(wildcard $(root)/libs/drawtext/*.c) \ 38.9 + $(wildcard $(root)/libs/vmath/*.c) 38.10 + 38.11 +ccsrc = $(wildcard $(root)/src/*.cc) \ 38.12 + $(wildcard $(root)/libs/vmath/*.cc) 38.13 + 38.14 bin = photoshoot3d 38.15 title = 3D Photo Shoot 38.16 38.17 -incpaths = -I$(root)/src 38.18 +incpaths = -I$(root)/src -I$(root)/libs -I$(root)/libs/vmath -I$(root)/libs/drawtext 38.19 libpaths = 38.20 +defs = -DNO_FREETYPE
39.1 --- a/src/android/amain.c Mon May 25 05:27:26 2015 +0300 39.2 +++ b/src/android/amain.c Sun May 31 00:40:26 2015 +0300 39.3 @@ -217,14 +217,14 @@ 39.4 { 39.5 static const int eglattr[] = { 39.6 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 39.7 - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, 39.8 + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 39.9 EGL_RED_SIZE, 5, 39.10 EGL_GREEN_SIZE, 5, 39.11 EGL_BLUE_SIZE, 5, 39.12 EGL_DEPTH_SIZE, 16, 39.13 EGL_NONE 39.14 }; 39.15 - static const int ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; 39.16 + static const int ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 39.17 39.18 EGLConfig eglcfg; 39.19 int count, vis;
40.1 --- a/src/game.c Mon May 25 05:27:26 2015 +0300 40.2 +++ b/src/game.c Sun May 31 00:40:26 2015 +0300 40.3 @@ -4,6 +4,7 @@ 40.4 #include "opengl.h" 40.5 #include "game.h" 40.6 #include "camera.h" 40.7 +#include "sdr.h" 40.8 40.9 static void draw_quad(float hsz, float vsz); 40.10 40.11 @@ -11,16 +12,57 @@ 40.12 static float win_aspect; 40.13 static int video_width, video_height; 40.14 static float video_aspect; 40.15 +static unsigned int sdrprog; 40.16 +static int aloc_vertex, aloc_texcoord, uloc_texmat, uloc_wmat, uloc_vmat, uloc_pmat; 40.17 + 40.18 +static const char *vsdr_source = 40.19 + "attribute vec4 attr_pos, attr_tex;\n" 40.20 + "uniform mat4 world_matrix, proj_matrix, tex_matrix;\n" 40.21 + "varying vec4 tex_coords;\n" 40.22 + "void main()\n" 40.23 + "{\n" 40.24 + "\tmat4 mvp = proj_matrix * world_matrix;\n" 40.25 + "\tgl_Position = mvp * attr_pos;\n" 40.26 + "\ttex_coords = tex_matrix * attr_tex;\n" 40.27 + "}\n"; 40.28 + 40.29 +static const char *psdr_source = 40.30 + "#extension GL_OES_EGL_image_external : require\n" 40.31 + "precision lowp float;\n" 40.32 + "uniform samplerExternalOES tex;\n" 40.33 + "varying vec4 tex_coords;\n" 40.34 + "void main()\n" 40.35 + "{\n" 40.36 + "\tvec4 texel = texture2D(tex, tex_coords.xy);\n" 40.37 + "\tgl_FragColor = vec4(texel.xyz, 1.0);\n" 40.38 + "}\n"; 40.39 40.40 40.41 int game_init(void) 40.42 { 40.43 + unsigned int vsdr, psdr; 40.44 + 40.45 glEnable(GL_DEPTH_TEST); 40.46 glEnable(GL_CULL_FACE); 40.47 - //glEnable(GL_LIGHTING); 40.48 40.49 glClearColor(0.4, 0.4, 0.4, 1); 40.50 40.51 + if(!(vsdr = create_vertex_shader(vsdr_source))) 40.52 + return -1; 40.53 + if(!(psdr = create_pixel_shader(psdr_source))) 40.54 + return -1; 40.55 + if(!(sdrprog = create_program_link(vsdr, psdr))) { 40.56 + fprintf(stderr, "failed to create shader program\n"); 40.57 + return -1; 40.58 + } 40.59 + glUseProgram(sdrprog); 40.60 + aloc_vertex = glGetAttribLocation(sdrprog, "attr_pos"); 40.61 + aloc_texcoord = glGetAttribLocation(sdrprog, "attr_tex"); 40.62 + uloc_texmat = glGetUniformLocation(sdrprog, "tex_matrix"); 40.63 + uloc_wmat = glGetUniformLocation(sdrprog, "world_matrix"); 40.64 + uloc_vmat = glGetUniformLocation(sdrprog, "view_matrix"); 40.65 + uloc_pmat = glGetUniformLocation(sdrprog, "proj_matrix"); 40.66 + 40.67 cam_start_video(); 40.68 cam_video_size(&video_width, &video_height); 40.69 if(video_height) { 40.70 @@ -36,6 +78,7 @@ 40.71 void game_shutdown(void) 40.72 { 40.73 cam_shutdown(); 40.74 + free_program(sdrprog); 40.75 } 40.76 40.77 void game_display(unsigned long msec) 40.78 @@ -53,17 +96,9 @@ 40.79 //glClearColor(sin(tsec * 10.0), cos(tsec * 10.0), -sin(tsec * 10.0), 1.0); 40.80 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 40.81 40.82 - glMatrixMode(GL_MODELVIEW); 40.83 - glLoadIdentity(); 40.84 - 40.85 - if(tex) { 40.86 - glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); 40.87 - glEnable(GL_TEXTURE_EXTERNAL_OES); 40.88 - 40.89 - glMatrixMode(GL_TEXTURE); 40.90 - glLoadMatrixf(tex_matrix); 40.91 - glMatrixMode(GL_MODELVIEW); 40.92 - } 40.93 + glUseProgram(sdrprog); 40.94 + glUniformMatrix4fv(uloc_texmat, 1, 0, tex_matrix); 40.95 + glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); 40.96 40.97 if(video_aspect > win_aspect) { 40.98 xscale = 1.0; 40.99 @@ -73,40 +108,35 @@ 40.100 yscale = 1.0; 40.101 } 40.102 draw_quad(xscale, yscale); 40.103 - 40.104 - if(tex) { 40.105 - glDisable(GL_TEXTURE_EXTERNAL_OES); 40.106 - 40.107 - glMatrixMode(GL_TEXTURE); 40.108 - glLoadIdentity(); 40.109 - glMatrixMode(GL_MODELVIEW); 40.110 - } 40.111 } 40.112 40.113 static void draw_quad(float hsz, float vsz) 40.114 { 40.115 static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1}; 40.116 static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1}; 40.117 - static const float colarr[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 40.118 + float xform[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; 40.119 40.120 - glPushMatrix(); 40.121 - glScalef(hsz, vsz, 1); 40.122 + if(aloc_vertex == -1) { 40.123 + return; 40.124 + } 40.125 40.126 - glEnableClientState(GL_VERTEX_ARRAY); 40.127 - glEnableClientState(GL_TEXTURE_COORD_ARRAY); 40.128 - glEnableClientState(GL_COLOR_ARRAY); 40.129 + xform[0] = hsz; 40.130 + xform[5] = vsz; 40.131 + glUniformMatrix4fv(uloc_wmat, 1, 0, xform); 40.132 40.133 - glVertexPointer(2, GL_FLOAT, 0, varr); 40.134 - glTexCoordPointer(2, GL_FLOAT, 0, tcarr); 40.135 - glColorPointer(4, GL_FLOAT, 0, colarr); 40.136 + glEnableVertexAttribArray(aloc_vertex); 40.137 + glVertexAttribPointer(aloc_vertex, 2, GL_FLOAT, 0, 0, varr); 40.138 + if(aloc_texcoord) { 40.139 + glEnableVertexAttribArray(aloc_texcoord); 40.140 + glVertexAttribPointer(aloc_texcoord, 2, GL_FLOAT, 0, 0, tcarr); 40.141 + } 40.142 40.143 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 40.144 40.145 - glDisableClientState(GL_VERTEX_ARRAY); 40.146 - glDisableClientState(GL_TEXTURE_COORD_ARRAY); 40.147 - glDisableClientState(GL_COLOR_ARRAY); 40.148 - 40.149 - glPopMatrix(); 40.150 + glDisableVertexAttribArray(aloc_vertex); 40.151 + if(aloc_texcoord) { 40.152 + glDisableVertexAttribArray(aloc_texcoord); 40.153 + } 40.154 } 40.155 40.156 void game_reshape(int x, int y) 40.157 @@ -116,9 +146,9 @@ 40.158 win_aspect = y ? (float)x / (float)y : 1.0; 40.159 glViewport(0, 0, x, y); 40.160 40.161 - glMatrixMode(GL_PROJECTION); 40.162 + /*glMatrixMode(GL_PROJECTION); 40.163 glLoadIdentity(); 40.164 - glScalef((float)win_height / (float)win_width, 1.0, 1.0); 40.165 + glScalef((float)win_height / (float)win_width, 1.0, 1.0);*/ 40.166 } 40.167 40.168 void game_keyboard(int key, int pressed)
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/src/gfxstate.cc Sun May 31 00:40:26 2015 +0300 41.3 @@ -0,0 +1,68 @@ 41.4 +#include <stack> 41.5 +#include "vmath/vmath.h" 41.6 +#include "gfxstate.h" 41.7 + 41.8 +static std::stack<Matrix4x4> mstack[NUM_MATRICES]; 41.9 + 41.10 +static bool init_stack(int midx) 41.11 +{ 41.12 + if(mstack[midx].empty()) { 41.13 + mstack[midx].push(Matrix4x4::identity); 41.14 + return true; 41.15 + } 41.16 + return false; 41.17 +} 41.18 + 41.19 +void push_matrix(int midx) 41.20 +{ 41.21 + init_stack(midx); 41.22 + mstack[midx].push(mstack[midx].top()); 41.23 +} 41.24 + 41.25 +void pop_matrix(int midx) 41.26 +{ 41.27 + if(!mstack[midx].empty()) { 41.28 + mstack[midx].pop(); 41.29 + } 41.30 +} 41.31 + 41.32 +void set_identity_matrix(int midx) 41.33 +{ 41.34 + set_matrix4x4(midx, Matrix4x4::identity); 41.35 +} 41.36 + 41.37 +void set_matrix(int midx, const float *m) 41.38 +{ 41.39 + Matrix4x4 tmp; 41.40 + memcpy(tmp[0], m, 16 * sizeof *m); 41.41 + set_matrix4x4(midx, tmp.transposed()); 41.42 +} 41.43 + 41.44 +void mult_matrix(int midx, const float *m) 41.45 +{ 41.46 + Matrix4x4 tmp; 41.47 + memcpy(tmp[0], m, 16 * sizeof *m); 41.48 + mult_matrix4x4(midx, tmp.transposed()); 41.49 +} 41.50 + 41.51 +void get_matrix(int midx, float *m) 41.52 +{ 41.53 + Matrix4x4 tmp = get_matrix4x4(midx); 41.54 + tmp.transpose(); 41.55 + memcpy(m, tmp[0], 16 * sizeof *m); 41.56 +} 41.57 + 41.58 +void set_matrix4x4(int midx, const Matrix4x4 &m) 41.59 +{ 41.60 + mstack[midx].top() = m; 41.61 +} 41.62 + 41.63 +void mult_matrix4x4(int midx, const Matrix4x4 &m) 41.64 +{ 41.65 + mstack[midx].top() *= m; 41.66 +} 41.67 + 41.68 +Matrix4x4 &get_matrix4x4(int midx) 41.69 +{ 41.70 + return mstack[midx].top(); 41.71 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/src/gfxstate.h Sun May 31 00:40:26 2015 +0300 42.3 @@ -0,0 +1,37 @@ 42.4 +#ifndef GFXSTATE_H_ 42.5 +#define GFXSTATE_H_ 42.6 + 42.7 +enum { 42.8 + WORLD_MATRIX, 42.9 + VIEW_MATRIX, 42.10 + PROJECTION_MATRIX, 42.11 + TEXTURE_MATRIX, 42.12 + 42.13 + NUM_MATRICES 42.14 +}; 42.15 + 42.16 +#ifdef __cplusplus 42.17 +extern "C" { 42.18 +#endif 42.19 + 42.20 +void push_matrix(int midx); 42.21 +void pop_matrix(int midx); 42.22 + 42.23 +void set_identity_matrix(int midx); 42.24 +void set_matrix(int midx, const float *m); 42.25 +void mult_matrix(int midx, const float *m); 42.26 +void get_matrix(int midx, float *m); 42.27 +float *get_matrix_ptr(int midx); 42.28 + 42.29 +#ifdef __cplusplus 42.30 +} 42.31 + 42.32 +#ifdef VMATH_MATRIX_H_ 42.33 +void set_matrix4x4(int midx, const Matrix4x4 &m); 42.34 +void mult_matrix4x4(int midx, const Matrix4x4 &m); 42.35 +Matrix4x4 &get_matrix4x4(int midx); 42.36 +#endif /* VMATH_MATRIX_H_ */ 42.37 + 42.38 +#endif /* __cplusplus */ 42.39 + 42.40 +#endif /* GFXSTATE_H_ */
43.1 --- a/src/opengl.h Mon May 25 05:27:26 2015 +0300 43.2 +++ b/src/opengl.h Sun May 31 00:40:26 2015 +0300 43.3 @@ -1,7 +1,12 @@ 43.4 #ifndef OPENGL_H_ 43.5 #define OPENGL_H_ 43.6 43.7 -#include <GLES/gl.h> 43.8 -#include <GLES/glext.h> 43.9 + 43.10 +#ifdef ANDROID 43.11 +#include <GLES2/gl2.h> 43.12 +#include <GLES2/gl2ext.h> 43.13 +#else 43.14 +#include <GL/glew.h> 43.15 +#endif 43.16 43.17 #endif /* OPENGL_H_ */
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/src/sdr.c Sun May 31 00:40:26 2015 +0300 44.3 @@ -0,0 +1,412 @@ 44.4 +#include <stdio.h> 44.5 +#include <stdlib.h> 44.6 +#include <string.h> 44.7 +#include <errno.h> 44.8 +#include <stdarg.h> 44.9 +#include <assert.h> 44.10 +#include "opengl.h" 44.11 + 44.12 +#if defined(unix) || defined(__unix__) 44.13 +#include <unistd.h> 44.14 +#include <sys/stat.h> 44.15 +#endif /* unix */ 44.16 + 44.17 +#include "sdr.h" 44.18 + 44.19 +static const char *sdrtypestr(unsigned int sdrtype); 44.20 + 44.21 +unsigned int create_vertex_shader(const char *src) 44.22 +{ 44.23 + return create_shader(src, GL_VERTEX_SHADER); 44.24 +} 44.25 + 44.26 +unsigned int create_pixel_shader(const char *src) 44.27 +{ 44.28 + return create_shader(src, GL_FRAGMENT_SHADER); 44.29 +} 44.30 + 44.31 +unsigned int create_tessctl_shader(const char *src) 44.32 +{ 44.33 +#ifdef GL_TESS_CONTROL_SHADER 44.34 + return create_shader(src, GL_TESS_CONTROL_SHADER); 44.35 +#else 44.36 + return 0; 44.37 +#endif 44.38 +} 44.39 + 44.40 +unsigned int create_tesseval_shader(const char *src) 44.41 +{ 44.42 +#ifdef GL_TESS_EVALUATION_SHADER 44.43 + return create_shader(src, GL_TESS_EVALUATION_SHADER); 44.44 +#else 44.45 + return 0; 44.46 +#endif 44.47 +} 44.48 + 44.49 +unsigned int create_geometry_shader(const char *src) 44.50 +{ 44.51 +#ifdef GL_GEOMETRY_SHADER 44.52 + return create_shader(src, GL_GEOMETRY_SHADER); 44.53 +#else 44.54 + return 0; 44.55 +#endif 44.56 +} 44.57 + 44.58 +unsigned int create_shader(const char *src, unsigned int sdr_type) 44.59 +{ 44.60 + unsigned int sdr; 44.61 + int success, info_len; 44.62 + char *info_str = 0; 44.63 + GLenum err; 44.64 + 44.65 + sdr = glCreateShader(sdr_type); 44.66 + assert(glGetError() == GL_NO_ERROR); 44.67 + glShaderSource(sdr, 1, &src, 0); 44.68 + err = glGetError(); 44.69 + assert(err == GL_NO_ERROR); 44.70 + glCompileShader(sdr); 44.71 + assert(glGetError() == GL_NO_ERROR); 44.72 + 44.73 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); 44.74 + assert(glGetError() == GL_NO_ERROR); 44.75 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); 44.76 + assert(glGetError() == GL_NO_ERROR); 44.77 + 44.78 + if(info_len) { 44.79 + if((info_str = malloc(info_len + 1))) { 44.80 + glGetShaderInfoLog(sdr, info_len, 0, info_str); 44.81 + assert(glGetError() == GL_NO_ERROR); 44.82 + info_str[info_len] = 0; 44.83 + } 44.84 + } 44.85 + 44.86 + if(success) { 44.87 + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); 44.88 + } else { 44.89 + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); 44.90 + glDeleteShader(sdr); 44.91 + sdr = 0; 44.92 + } 44.93 + 44.94 + free(info_str); 44.95 + return sdr; 44.96 +} 44.97 + 44.98 +void free_shader(unsigned int sdr) 44.99 +{ 44.100 + glDeleteShader(sdr); 44.101 +} 44.102 + 44.103 +unsigned int load_vertex_shader(const char *fname) 44.104 +{ 44.105 + return load_shader(fname, GL_VERTEX_SHADER); 44.106 +} 44.107 + 44.108 +unsigned int load_pixel_shader(const char *fname) 44.109 +{ 44.110 + return load_shader(fname, GL_FRAGMENT_SHADER); 44.111 +} 44.112 + 44.113 +unsigned int load_tessctl_shader(const char *fname) 44.114 +{ 44.115 +#ifdef GL_TESS_CONTROL_SHADER 44.116 + return load_shader(fname, GL_TESS_CONTROL_SHADER); 44.117 +#else 44.118 + return 0; 44.119 +#endif 44.120 +} 44.121 + 44.122 +unsigned int load_tesseval_shader(const char *fname) 44.123 +{ 44.124 +#ifdef GL_TESS_EVALUATION_SHADER 44.125 + return load_shader(fname, GL_TESS_EVALUATION_SHADER); 44.126 +#else 44.127 + return 0; 44.128 +#endif 44.129 +} 44.130 + 44.131 +unsigned int load_geometry_shader(const char *fname) 44.132 +{ 44.133 +#ifdef GL_GEOMETRY_SHADER 44.134 + return load_shader(fname, GL_GEOMETRY_SHADER); 44.135 +#else 44.136 + return 0; 44.137 +#endif 44.138 +} 44.139 + 44.140 +unsigned int load_shader(const char *fname, unsigned int sdr_type) 44.141 +{ 44.142 +#if defined(unix) || defined(__unix__) 44.143 + struct stat st; 44.144 +#endif 44.145 + unsigned int sdr; 44.146 + size_t filesize; 44.147 + FILE *fp; 44.148 + char *src; 44.149 + 44.150 + if(!(fp = fopen(fname, "rb"))) { 44.151 + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); 44.152 + return 0; 44.153 + } 44.154 + 44.155 +#if defined(unix) || defined(__unix__) 44.156 + fstat(fileno(fp), &st); 44.157 + filesize = st.st_size; 44.158 +#else 44.159 + fseek(fp, 0, SEEK_END); 44.160 + filesize = ftell(fp); 44.161 + fseek(fp, 0, SEEK_SET); 44.162 +#endif /* unix */ 44.163 + 44.164 + if(!(src = malloc(filesize + 1))) { 44.165 + fclose(fp); 44.166 + return 0; 44.167 + } 44.168 + fread(src, 1, filesize, fp); 44.169 + src[filesize] = 0; 44.170 + fclose(fp); 44.171 + 44.172 + fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname); 44.173 + sdr = create_shader(src, sdr_type); 44.174 + 44.175 + free(src); 44.176 + return sdr; 44.177 +} 44.178 + 44.179 + 44.180 +/* ---- gpu programs ---- */ 44.181 + 44.182 +unsigned int create_program(void) 44.183 +{ 44.184 + unsigned int prog = glCreateProgram(); 44.185 + assert(glGetError() == GL_NO_ERROR); 44.186 + return prog; 44.187 +} 44.188 + 44.189 +unsigned int create_program_link(unsigned int sdr0, ...) 44.190 +{ 44.191 + unsigned int prog, sdr; 44.192 + va_list ap; 44.193 + 44.194 + if(!(prog = create_program())) { 44.195 + return 0; 44.196 + } 44.197 + 44.198 + attach_shader(prog, sdr0); 44.199 + if(glGetError()) { 44.200 + return 0; 44.201 + } 44.202 + 44.203 + va_start(ap, sdr0); 44.204 + while((sdr = va_arg(ap, unsigned int))) { 44.205 + attach_shader(prog, sdr); 44.206 + if(glGetError()) { 44.207 + return 0; 44.208 + } 44.209 + } 44.210 + va_end(ap); 44.211 + 44.212 + if(link_program(prog) == -1) { 44.213 + free_program(prog); 44.214 + return 0; 44.215 + } 44.216 + return prog; 44.217 +} 44.218 + 44.219 +unsigned int create_program_load(const char *vfile, const char *pfile) 44.220 +{ 44.221 + unsigned int vs = 0, ps = 0; 44.222 + 44.223 + if(vfile && *vfile && !(vs = load_vertex_shader(vfile))) { 44.224 + return 0; 44.225 + } 44.226 + if(pfile && *pfile && !(ps = load_pixel_shader(pfile))) { 44.227 + return 0; 44.228 + } 44.229 + return create_program_link(vs, ps, 0); 44.230 +} 44.231 + 44.232 +void free_program(unsigned int sdr) 44.233 +{ 44.234 + glDeleteProgram(sdr); 44.235 +} 44.236 + 44.237 +void attach_shader(unsigned int prog, unsigned int sdr) 44.238 +{ 44.239 + if(prog && sdr) { 44.240 + glAttachShader(prog, sdr); 44.241 + if(glGetError() != GL_NO_ERROR) { 44.242 + fprintf(stderr, "failed to attach shader %u to program %u\n", sdr, prog); 44.243 + abort(); 44.244 + } 44.245 + } 44.246 +} 44.247 + 44.248 +int link_program(unsigned int prog) 44.249 +{ 44.250 + int linked, info_len, retval = 0; 44.251 + char *info_str = 0; 44.252 + 44.253 + glLinkProgram(prog); 44.254 + assert(glGetError() == GL_NO_ERROR); 44.255 + glGetProgramiv(prog, GL_LINK_STATUS, &linked); 44.256 + assert(glGetError() == GL_NO_ERROR); 44.257 + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); 44.258 + assert(glGetError() == GL_NO_ERROR); 44.259 + 44.260 + if(info_len) { 44.261 + if((info_str = malloc(info_len + 1))) { 44.262 + glGetProgramInfoLog(prog, info_len, 0, info_str); 44.263 + assert(glGetError() == GL_NO_ERROR); 44.264 + info_str[info_len] = 0; 44.265 + } 44.266 + } 44.267 + 44.268 + if(linked) { 44.269 + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); 44.270 + } else { 44.271 + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); 44.272 + retval = -1; 44.273 + } 44.274 + 44.275 + free(info_str); 44.276 + return retval; 44.277 +} 44.278 + 44.279 +int bind_program(unsigned int prog) 44.280 +{ 44.281 + GLenum err; 44.282 + 44.283 + glUseProgram(prog); 44.284 + if(prog && (err = glGetError()) != GL_NO_ERROR) { 44.285 + /* maybe the program is not linked, try linking first */ 44.286 + if(err == GL_INVALID_OPERATION) { 44.287 + if(link_program(prog) == -1) { 44.288 + return -1; 44.289 + } 44.290 + glUseProgram(prog); 44.291 + return glGetError() == GL_NO_ERROR ? 0 : -1; 44.292 + } 44.293 + return -1; 44.294 + } 44.295 + return 0; 44.296 +} 44.297 + 44.298 +/* ugly but I'm not going to write the same bloody code over and over */ 44.299 +#define BEGIN_UNIFORM_CODE \ 44.300 + int loc, curr_prog; \ 44.301 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ 44.302 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ 44.303 + return -1; \ 44.304 + } \ 44.305 + if((loc = glGetUniformLocation(prog, name)) != -1) 44.306 + 44.307 +#define END_UNIFORM_CODE \ 44.308 + if((unsigned int)curr_prog != prog) { \ 44.309 + bind_program(curr_prog); \ 44.310 + } \ 44.311 + return loc == -1 ? -1 : 0 44.312 + 44.313 +int set_uniform_int(unsigned int prog, const char *name, int val) 44.314 +{ 44.315 + BEGIN_UNIFORM_CODE { 44.316 + glUniform1i(loc, val); 44.317 + } 44.318 + END_UNIFORM_CODE; 44.319 +} 44.320 + 44.321 +int set_uniform_float(unsigned int prog, const char *name, float val) 44.322 +{ 44.323 + BEGIN_UNIFORM_CODE { 44.324 + glUniform1f(loc, val); 44.325 + } 44.326 + END_UNIFORM_CODE; 44.327 +} 44.328 + 44.329 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y) 44.330 +{ 44.331 + BEGIN_UNIFORM_CODE { 44.332 + glUniform2f(loc, x, y); 44.333 + } 44.334 + END_UNIFORM_CODE; 44.335 +} 44.336 + 44.337 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) 44.338 +{ 44.339 + BEGIN_UNIFORM_CODE { 44.340 + glUniform3f(loc, x, y, z); 44.341 + } 44.342 + END_UNIFORM_CODE; 44.343 +} 44.344 + 44.345 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) 44.346 +{ 44.347 + BEGIN_UNIFORM_CODE { 44.348 + glUniform4f(loc, x, y, z, w); 44.349 + } 44.350 + END_UNIFORM_CODE; 44.351 +} 44.352 + 44.353 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) 44.354 +{ 44.355 + BEGIN_UNIFORM_CODE { 44.356 + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 44.357 + } 44.358 + END_UNIFORM_CODE; 44.359 +} 44.360 + 44.361 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) 44.362 +{ 44.363 + BEGIN_UNIFORM_CODE { 44.364 + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); 44.365 + } 44.366 + END_UNIFORM_CODE; 44.367 +} 44.368 + 44.369 +int get_attrib_loc(unsigned int prog, const char *name) 44.370 +{ 44.371 + int loc, curr_prog; 44.372 + 44.373 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 44.374 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { 44.375 + return -1; 44.376 + } 44.377 + 44.378 + loc = glGetAttribLocation(prog, (char*)name); 44.379 + 44.380 + if((unsigned int)curr_prog != prog) { 44.381 + bind_program(curr_prog); 44.382 + } 44.383 + return loc; 44.384 +} 44.385 + 44.386 +void set_attrib_float3(int attr_loc, float x, float y, float z) 44.387 +{ 44.388 + glVertexAttrib3f(attr_loc, x, y, z); 44.389 +} 44.390 + 44.391 +static const char *sdrtypestr(unsigned int sdrtype) 44.392 +{ 44.393 + switch(sdrtype) { 44.394 + case GL_VERTEX_SHADER: 44.395 + return "vertex"; 44.396 + case GL_FRAGMENT_SHADER: 44.397 + return "pixel"; 44.398 +#ifdef GL_TESS_CONTROL_SHADER 44.399 + case GL_TESS_CONTROL_SHADER: 44.400 + return "tessellation control"; 44.401 +#endif 44.402 +#ifdef GL_TESS_EVALUATION_SHADER 44.403 + case GL_TESS_EVALUATION_SHADER: 44.404 + return "tessellation evaluation"; 44.405 +#endif 44.406 +#ifdef GL_GEOMETRY_SHADER 44.407 + case GL_GEOMETRY_SHADER: 44.408 + return "geometry"; 44.409 +#endif 44.410 + 44.411 + default: 44.412 + break; 44.413 + } 44.414 + return "<unknown>"; 44.415 +}
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/src/sdr.h Sun May 31 00:40:26 2015 +0300 45.3 @@ -0,0 +1,52 @@ 45.4 +#ifndef SDR_H_ 45.5 +#define SDR_H_ 45.6 + 45.7 +#ifdef __cplusplus 45.8 +extern "C" { 45.9 +#endif /* __cplusplus */ 45.10 + 45.11 +/* ---- shaders ---- */ 45.12 +unsigned int create_vertex_shader(const char *src); 45.13 +unsigned int create_pixel_shader(const char *src); 45.14 +unsigned int create_tessctl_shader(const char *src); 45.15 +unsigned int create_tesseval_shader(const char *src); 45.16 +unsigned int create_geometry_shader(const char *src); 45.17 +unsigned int create_shader(const char *src, unsigned int sdr_type); 45.18 +void free_shader(unsigned int sdr); 45.19 + 45.20 +unsigned int load_vertex_shader(const char *fname); 45.21 +unsigned int load_pixel_shader(const char *fname); 45.22 +unsigned int load_tessctl_shader(const char *fname); 45.23 +unsigned int load_tesseval_shader(const char *fname); 45.24 +unsigned int load_geometry_shader(const char *fname); 45.25 +unsigned int load_shader(const char *src, unsigned int sdr_type); 45.26 + 45.27 +int add_shader(const char *fname, unsigned int sdr); 45.28 +int remove_shader(const char *fname); 45.29 + 45.30 +/* ---- gpu programs ---- */ 45.31 +unsigned int create_program(void); 45.32 +unsigned int create_program_link(unsigned int sdr0, ...); 45.33 +unsigned int create_program_load(const char *vfile, const char *pfile); 45.34 +void free_program(unsigned int sdr); 45.35 + 45.36 +void attach_shader(unsigned int prog, unsigned int sdr); 45.37 +int link_program(unsigned int prog); 45.38 +int bind_program(unsigned int prog); 45.39 + 45.40 +int set_uniform_int(unsigned int prog, const char *name, int val); 45.41 +int set_uniform_float(unsigned int prog, const char *name, float val); 45.42 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y); 45.43 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); 45.44 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); 45.45 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat); 45.46 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat); 45.47 + 45.48 +int get_attrib_loc(unsigned int prog, const char *name); 45.49 +void set_attrib_float3(int attr_loc, float x, float y, float z); 45.50 + 45.51 +#ifdef __cplusplus 45.52 +} 45.53 +#endif /* __cplusplus */ 45.54 + 45.55 +#endif /* SDR_H_ */