From b690084e9c682b8e0620a35d3b53134f9a0fd4a0 Mon Sep 17 00:00:00 2001 From: Florent Berthaut <florent.berthaut@univ-lille.fr> Date: Thu, 22 Dec 2022 01:16:32 +0100 Subject: [PATCH] First commit --- .gitattributes | 1 + .gitignore | 7 + COPYING | 674 +++++ README.md | 177 +- data/Info.plist | 27 + data/build_linuxapp.sh | 8 + data/build_macapp.sh | 11 + data/revil.desktop | 13 + data/revil.icns | Bin 0 -> 40371 bytes data/revil.png | Bin 0 -> 19943 bytes data/revil.svg | 159 ++ data/revil.xml | 4 + src/Reveal.cpp | 718 +++++ src/Reveal.hpp | 272 ++ src/audio/AudioManager.hpp | 41 + src/geoms/BoxGeometry.cpp | 116 + src/geoms/BoxGeometry.hpp | 38 + src/geoms/CamGeometry.cpp | 70 + src/geoms/CamGeometry.hpp | 40 + src/geoms/ConeGeometry.cpp | 71 + src/geoms/ConeGeometry.hpp | 38 + src/geoms/FrameGeometry.cpp | 131 + src/geoms/FrameGeometry.hpp | 38 + src/geoms/Geometry.cpp | 168 ++ src/geoms/Geometry.hpp | 80 + src/geoms/QuadGeometry.cpp | 60 + src/geoms/QuadGeometry.hpp | 38 + src/geoms/SphereGeometry.cpp | 84 + src/geoms/SphereGeometry.hpp | 38 + src/geoms/TubeGeometry.cpp | 73 + src/geoms/TubeGeometry.hpp | 38 + src/gui/AttributeWidget.cpp | 517 ++++ src/gui/AttributeWidget.hpp | 134 + src/gui/GuiListener.cpp | 45 + src/gui/GuiListener.hpp | 45 + src/gui/ListenerWidget.cpp | 109 + src/gui/ListenerWidget.hpp | 57 + src/gui/MainWindow.cpp | 250 ++ src/gui/MainWindow.hpp | 90 + src/gui/ModuleWidget.cpp | 58 + src/gui/ModuleWidget.hpp | 44 + src/modules/Attribute.cpp | 316 +++ src/modules/Attribute.hpp | 330 +++ src/modules/ContextHandler.hpp | 50 + src/modules/DepthCamModule.cpp | 1805 ++++++++++++ src/modules/DepthCamModule.hpp | 406 +++ src/modules/DepthGroupModule.cpp | 116 + src/modules/DepthGroupModule.hpp | 83 + src/modules/DepthMeshModule.cpp | 97 + src/modules/DepthMeshModule.hpp | 55 + src/modules/DepthModule.cpp | 63 + src/modules/DepthModule.hpp | 60 + src/modules/DepthShapeModule.cpp | 83 + src/modules/DepthShapeModule.hpp | 42 + src/modules/GeomModule.cpp | 63 + src/modules/GeomModule.hpp | 57 + src/modules/GroupModule.cpp | 162 ++ src/modules/GroupModule.hpp | 59 + src/modules/Listener.cpp | 73 + src/modules/Listener.hpp | 72 + src/modules/ModelModule.cpp | 286 ++ src/modules/ModelModule.hpp | 72 + src/modules/Module.cpp | 423 +++ src/modules/Module.hpp | 238 ++ src/modules/OutputManagerModule.cpp | 60 + src/modules/OutputManagerModule.hpp | 54 + src/modules/OutputOscModule.cpp | 58 + src/modules/OutputOscModule.hpp | 53 + src/modules/OutputPdModule.cpp | 37 + src/modules/OutputPdModule.hpp | 39 + src/modules/PreviewModule.cpp | 315 +++ src/modules/PreviewModule.hpp | 108 + src/modules/ProjectorModule.cpp | 2419 ++++++++++++++++ src/modules/ProjectorModule.hpp | 227 ++ src/modules/RevealedArrowModule.cpp | 348 +++ src/modules/RevealedArrowModule.hpp | 199 ++ src/modules/RevealedCutModule.cpp | 393 +++ src/modules/RevealedCutModule.hpp | 160 ++ src/modules/RevealedGridModule.cpp | 202 ++ src/modules/RevealedGridModule.hpp | 126 + src/modules/RevealedModelModule.cpp | 114 + src/modules/RevealedModelModule.hpp | 54 + src/modules/RevealedModule.cpp | 1797 ++++++++++++ src/modules/RevealedModule.hpp | 469 ++++ src/modules/RevealedPathModule.cpp | 446 +++ src/modules/RevealedPathModule.hpp | 134 + src/modules/RevealedShapeModule.cpp | 76 + src/modules/RevealedShapeModule.hpp | 44 + src/modules/RevealedTextModule.cpp | 200 ++ src/modules/RevealedTextModule.hpp | 68 + src/modules/RootSceneGroupModule.cpp | 131 + src/modules/RootSceneGroupModule.hpp | 77 + src/modules/SceneGroupModule.cpp | 40 + src/modules/SceneGroupModule.hpp | 66 + src/modules/ShapeModule.cpp | 123 + src/modules/ShapeModule.hpp | 59 + src/modules/SpaceModule.cpp | 315 +++ src/modules/SpaceModule.hpp | 111 + src/osc/OscListener.cpp | 188 ++ src/osc/OscListener.hpp | 49 + src/osc/OscManager.cpp | 264 ++ src/osc/OscManager.hpp | 97 + src/osc/oscPack/ip/IpEndpointName.cpp | 88 + src/osc/oscPack/ip/IpEndpointName.h | 83 + src/osc/oscPack/ip/NetworkingUtils.h | 56 + src/osc/oscPack/ip/PacketListener.h | 50 + src/osc/oscPack/ip/TimerListener.h | 47 + src/osc/oscPack/ip/UdpSocket.h | 176 ++ src/osc/oscPack/ip/posix/NetworkingUtils.cpp | 64 + src/osc/oscPack/ip/posix/UdpSocket.cpp | 605 ++++ src/osc/oscPack/ip/win32/NetworkingUtils.cpp | 95 + src/osc/oscPack/ip/win32/UdpSocket.cpp | 571 ++++ .../osc/MessageMappingOscPacketListener.h | 80 + src/osc/oscPack/osc/OscException.h | 62 + src/osc/oscPack/osc/OscHostEndianness.h | 127 + .../oscPack/osc/OscOutboundPacketStream.cpp | 683 +++++ src/osc/oscPack/osc/OscOutboundPacketStream.h | 154 + src/osc/oscPack/osc/OscPacketListener.h | 79 + .../oscPack/osc/OscPrintReceivedElements.cpp | 261 ++ .../oscPack/osc/OscPrintReceivedElements.h | 54 + src/osc/oscPack/osc/OscReceivedElements.cpp | 801 ++++++ src/osc/oscPack/osc/OscReceivedElements.h | 548 ++++ src/osc/oscPack/osc/OscTypes.cpp | 52 + src/osc/oscPack/osc/OscTypes.h | 240 ++ src/tags | 2475 +++++++++++++++++ src/utils/create_marker.cpp | 96 + waf | 173 ++ wscript | 138 + 128 files changed, 27083 insertions(+), 88 deletions(-) create mode 100755 .gitattributes create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 data/Info.plist create mode 100644 data/build_linuxapp.sh create mode 100755 data/build_macapp.sh create mode 100644 data/revil.desktop create mode 100644 data/revil.icns create mode 100644 data/revil.png create mode 100644 data/revil.svg create mode 100644 data/revil.xml create mode 100644 src/Reveal.cpp create mode 100644 src/Reveal.hpp create mode 100644 src/audio/AudioManager.hpp create mode 100644 src/geoms/BoxGeometry.cpp create mode 100644 src/geoms/BoxGeometry.hpp create mode 100644 src/geoms/CamGeometry.cpp create mode 100644 src/geoms/CamGeometry.hpp create mode 100644 src/geoms/ConeGeometry.cpp create mode 100644 src/geoms/ConeGeometry.hpp create mode 100644 src/geoms/FrameGeometry.cpp create mode 100644 src/geoms/FrameGeometry.hpp create mode 100644 src/geoms/Geometry.cpp create mode 100644 src/geoms/Geometry.hpp create mode 100644 src/geoms/QuadGeometry.cpp create mode 100644 src/geoms/QuadGeometry.hpp create mode 100644 src/geoms/SphereGeometry.cpp create mode 100644 src/geoms/SphereGeometry.hpp create mode 100644 src/geoms/TubeGeometry.cpp create mode 100644 src/geoms/TubeGeometry.hpp create mode 100644 src/gui/AttributeWidget.cpp create mode 100644 src/gui/AttributeWidget.hpp create mode 100644 src/gui/GuiListener.cpp create mode 100644 src/gui/GuiListener.hpp create mode 100644 src/gui/ListenerWidget.cpp create mode 100644 src/gui/ListenerWidget.hpp create mode 100755 src/gui/MainWindow.cpp create mode 100755 src/gui/MainWindow.hpp create mode 100644 src/gui/ModuleWidget.cpp create mode 100644 src/gui/ModuleWidget.hpp create mode 100644 src/modules/Attribute.cpp create mode 100644 src/modules/Attribute.hpp create mode 100644 src/modules/ContextHandler.hpp create mode 100644 src/modules/DepthCamModule.cpp create mode 100644 src/modules/DepthCamModule.hpp create mode 100644 src/modules/DepthGroupModule.cpp create mode 100644 src/modules/DepthGroupModule.hpp create mode 100644 src/modules/DepthMeshModule.cpp create mode 100644 src/modules/DepthMeshModule.hpp create mode 100644 src/modules/DepthModule.cpp create mode 100644 src/modules/DepthModule.hpp create mode 100644 src/modules/DepthShapeModule.cpp create mode 100644 src/modules/DepthShapeModule.hpp create mode 100644 src/modules/GeomModule.cpp create mode 100644 src/modules/GeomModule.hpp create mode 100644 src/modules/GroupModule.cpp create mode 100644 src/modules/GroupModule.hpp create mode 100644 src/modules/Listener.cpp create mode 100644 src/modules/Listener.hpp create mode 100644 src/modules/ModelModule.cpp create mode 100644 src/modules/ModelModule.hpp create mode 100644 src/modules/Module.cpp create mode 100644 src/modules/Module.hpp create mode 100644 src/modules/OutputManagerModule.cpp create mode 100644 src/modules/OutputManagerModule.hpp create mode 100644 src/modules/OutputOscModule.cpp create mode 100644 src/modules/OutputOscModule.hpp create mode 100644 src/modules/OutputPdModule.cpp create mode 100644 src/modules/OutputPdModule.hpp create mode 100644 src/modules/PreviewModule.cpp create mode 100644 src/modules/PreviewModule.hpp create mode 100644 src/modules/ProjectorModule.cpp create mode 100644 src/modules/ProjectorModule.hpp create mode 100644 src/modules/RevealedArrowModule.cpp create mode 100644 src/modules/RevealedArrowModule.hpp create mode 100644 src/modules/RevealedCutModule.cpp create mode 100644 src/modules/RevealedCutModule.hpp create mode 100644 src/modules/RevealedGridModule.cpp create mode 100644 src/modules/RevealedGridModule.hpp create mode 100644 src/modules/RevealedModelModule.cpp create mode 100644 src/modules/RevealedModelModule.hpp create mode 100644 src/modules/RevealedModule.cpp create mode 100644 src/modules/RevealedModule.hpp create mode 100644 src/modules/RevealedPathModule.cpp create mode 100644 src/modules/RevealedPathModule.hpp create mode 100644 src/modules/RevealedShapeModule.cpp create mode 100644 src/modules/RevealedShapeModule.hpp create mode 100644 src/modules/RevealedTextModule.cpp create mode 100644 src/modules/RevealedTextModule.hpp create mode 100644 src/modules/RootSceneGroupModule.cpp create mode 100644 src/modules/RootSceneGroupModule.hpp create mode 100644 src/modules/SceneGroupModule.cpp create mode 100644 src/modules/SceneGroupModule.hpp create mode 100644 src/modules/ShapeModule.cpp create mode 100644 src/modules/ShapeModule.hpp create mode 100644 src/modules/SpaceModule.cpp create mode 100644 src/modules/SpaceModule.hpp create mode 100644 src/osc/OscListener.cpp create mode 100644 src/osc/OscListener.hpp create mode 100644 src/osc/OscManager.cpp create mode 100644 src/osc/OscManager.hpp create mode 100644 src/osc/oscPack/ip/IpEndpointName.cpp create mode 100644 src/osc/oscPack/ip/IpEndpointName.h create mode 100644 src/osc/oscPack/ip/NetworkingUtils.h create mode 100644 src/osc/oscPack/ip/PacketListener.h create mode 100644 src/osc/oscPack/ip/TimerListener.h create mode 100644 src/osc/oscPack/ip/UdpSocket.h create mode 100644 src/osc/oscPack/ip/posix/NetworkingUtils.cpp create mode 100644 src/osc/oscPack/ip/posix/UdpSocket.cpp create mode 100644 src/osc/oscPack/ip/win32/NetworkingUtils.cpp create mode 100644 src/osc/oscPack/ip/win32/UdpSocket.cpp create mode 100644 src/osc/oscPack/osc/MessageMappingOscPacketListener.h create mode 100644 src/osc/oscPack/osc/OscException.h create mode 100644 src/osc/oscPack/osc/OscHostEndianness.h create mode 100644 src/osc/oscPack/osc/OscOutboundPacketStream.cpp create mode 100644 src/osc/oscPack/osc/OscOutboundPacketStream.h create mode 100644 src/osc/oscPack/osc/OscPacketListener.h create mode 100644 src/osc/oscPack/osc/OscPrintReceivedElements.cpp create mode 100644 src/osc/oscPack/osc/OscPrintReceivedElements.h create mode 100644 src/osc/oscPack/osc/OscReceivedElements.cpp create mode 100644 src/osc/oscPack/osc/OscReceivedElements.h create mode 100644 src/osc/oscPack/osc/OscTypes.cpp create mode 100644 src/osc/oscPack/osc/OscTypes.h create mode 100644 src/tags create mode 100644 src/utils/create_marker.cpp create mode 100755 waf create mode 100755 wscript diff --git a/.gitattributes b/.gitattributes new file mode 100755 index 0000000..77510b2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.pd binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..159d8d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +build +.w* +.idea +.lock-waf_linux2_build +cmake-build-debug +.* +node_modules diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/README.md b/README.md index 171fa81..502a1f7 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,93 @@ -# Rivill - - - -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.univ-lille.fr/mint/rivill.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://gitlab.univ-lille.fr/mint/rivill/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. +# Revil ## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. +Revil is an application for building and manipulating 3D SceneGraphs for +Mixed-Reality Artistic Performances and Digital Mediation. +It is based on OpenGL (glfw, glm), OpenNI2 +and is entirely controllable via OpenSoundControl messages. It relies on the +approach of revealing virtual content in the physical space by intersecting +it with performers and spectator's bodies and props. This content can be +used for visualisation, e.g. to augment digital performances or museum +cabinets, or for interaction, e.g. controlling sound with 3D widgets. + +For video examples of what Revil can do, watch https://vimeo.com/album/4703717 + +Revil has been used in the following projects: +* http://ixmi.hitmuri.net +* https://www.cristal.univ-lille.fr/mint/revealable-volume-displays.html +* https://www.cristal.univ-lille.fr/mint/revealed-interfaces.html +* https://terrev.univ-lille.fr/ + +## Help +A tutorial describing the main components of Revil is available +in [the doc folder](doc/tutorial.md). +Several examples are also provided. + +## Software requirements: +* OpenGL >= 4.3 (or >=3 but there will be no revealing output) + +## Hardware Requirements: +* Depth Camera (one handled by OpenNI2) +* Projector + +## Compiling / Installing on GNU/Linux +* Install the following packages : + * glm + * glfw >= 3.3 + * glew + * FLTK (http://fltk.org) >= 1.3.X + * OpenNI2 (http://structure.io/openni) + * OpenCV >=3 (http://opencv.org/) + with OpenCV Contrib aruco + * xml++2 + * assimp +* ./waf configure +* ./waf +* sudo ./waf install + + +## Compiling on Mac OSX +* Install command-line tools +* Install macports https://www.macports.org/install.php +* Open a terminal +* Install the following ports (sudo port install "port_name") + * glfw + * glm + * glew + * opencv3 +contrib + * fltk + * assimp + * libusb +* Install OpenNI2 + * Download https://github.com/occipital/OpenNI2/archive/refs/heads/master.zip + * Compile and install it : + * make + * make install +* Clone and compile the revil source code + * git clone https://gitlab.cristal.univ-lille.fr/fberthau/revil.git + * cd revil + * ./waf configure + * ./waf +* Start revil + * ./build/revil +* To create a .app + * Install https://github.com/auriamg/macdylibbundler + * In the revil/build folder, type : + * dylibbundler -od -b -x ./revil.app/Contents/MacOS/revil -d ./revil.app/Contents/libs/ + + +## Uses +* OscPack (http://www.rossbencina.com/code/oscpack) +* Calibration code from https://github.com/Kj1/ofxProjectorKinectCalibration +* 1€ filter by Casiez et al. http://cristal.univ-lille.fr/~casiez/1euro/ +* Signed distance functions from https://iquilezles.org/www/articles/distfunctions/distfunctions.htm + +## Authors: +* Florent Berthaut, Assistant Professor, Université de Lille, CRIStAL/MINT + florent_DOT_berthaut_AT_univ-lille_DOT_fr +* Alan Menit alanmenit_AT_gmail_DOT_com +* Boris Legal +* Anthony Beuchey +* Cagan Arslan -## License -For open source projects, say how it is licensed. -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. diff --git a/data/Info.plist b/data/Info.plist new file mode 100644 index 0000000..e9bc04e --- /dev/null +++ b/data/Info.plist @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>revil</string> + <key>CFBundleIconFile</key> + <string>revil.icns</string> + <key>CFBundleIdentifier</key> + <string>net.hitmuri.www</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>Revil</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>0.0.1</string> + <key>LSMinimumSystemVersion</key> + <string>10.4</string> + <key>CFBundleVersion</key> + <string>1</string> +</dict> +</plist> + diff --git a/data/build_linuxapp.sh b/data/build_linuxapp.sh new file mode 100644 index 0000000..0269e4a --- /dev/null +++ b/data/build_linuxapp.sh @@ -0,0 +1,8 @@ +#install all dependencies through synaptic +sudo apt-get install python3 libfltk1.3-dev libxml2++-dev + +#compile revil +./waf configure +./waf + +#create app diff --git a/data/build_macapp.sh b/data/build_macapp.sh new file mode 100755 index 0000000..e0aa90d --- /dev/null +++ b/data/build_macapp.sh @@ -0,0 +1,11 @@ +#install all dependencies through macports + +#compile revil +./waf configure +./waf + +#create app +cd build +dylibbundler -od -b -x ./revil.app/Contents/MacOS/revil -d ./revil.app/Contents/libs/ +cp -R /opt/local/lib/OpenNI2 revil.app/Contents/libs/ + diff --git a/data/revil.desktop b/data/revil.desktop new file mode 100644 index 0000000..520ef80 --- /dev/null +++ b/data/revil.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Name=Revil +Comment=3D Revealed Interfaces +Exec=/usr/local/bin/revil +Icon=revil +Terminal=false +Type=Application +Categories=AudioVideo; +Name[en_US]=revil.desktop +GenericName[en_US]=3D Revealed Interfaces +Comment[en_US]=3D Revealed Interfaces diff --git a/data/revil.icns b/data/revil.icns new file mode 100644 index 0000000000000000000000000000000000000000..a75da2a2869f74f7ca265973366d9e165cf6df81 GIT binary patch literal 40371 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 a|7>%EuLuq`G!^Eb@@8j?Kgtw4Ui$z!_a0FI literal 0 HcmV?d00001 diff --git a/data/revil.png b/data/revil.png new file mode 100644 index 0000000000000000000000000000000000000000..4228f2870ec49460c67bf4363d74c6f9afb8bb70 GIT binary patch literal 19943 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 FO#n-78A$*D literal 0 HcmV?d00001 diff --git a/data/revil.svg b/data/revil.svg new file mode 100644 index 0000000..56af93c --- /dev/null +++ b/data/revil.svg @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 744.09448819 1052.3622047" + id="svg2" + version="1.1" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)" + sodipodi:docname="revil.svg" + enable-background="new"> + <defs + id="defs4"> + <linearGradient + inkscape:collect="always" + id="linearGradient6513"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop6515" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop6517" /> + </linearGradient> + <linearGradient + id="linearGradient6030" + osb:paint="gradient"> + <stop + style="stop-color:#8c8c8c;stop-opacity:1;" + offset="0" + id="stop6032" /> + <stop + style="stop-color:#8c8c8c;stop-opacity:0;" + offset="1" + id="stop6034" /> + </linearGradient> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="-132.85714 : 497.60967 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="201.23735 : 663.32396 : 1" + inkscape:persp3d-origin="107.76153 : 116.50168 : 1" + id="perspective4511" /> + <linearGradient + inkscape:collect="always" + id="linearGradient4499"> + <stop + style="stop-color:#e03838;stop-opacity:1;" + offset="0" + id="stop4501" /> + <stop + style="stop-color:#e03838;stop-opacity:0;" + offset="1" + id="stop4503" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4499" + id="linearGradient4545" + gradientUnits="userSpaceOnUse" + x1="119.00173" + y1="176.68629" + x2="491.26828" + y2="176.68629" + gradientTransform="translate(77.142857,11.428571)" /> + <filter + inkscape:collect="always" + style="color-interpolation-filters:sRGB" + id="filter6463"> + <feBlend + inkscape:collect="always" + mode="screen" + in2="BackgroundImage" + id="feBlend6465" /> + </filter> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient6513" + id="radialGradient6519" + cx="260.49961" + cy="200.31575" + fx="260.49961" + fy="200.31575" + r="174.20097" + gradientTransform="matrix(1,0,0,0.36832117,0,126.53522)" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.49497475" + inkscape:cx="-446.62596" + inkscape:cy="898.65332" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1920" + inkscape:window-height="1018" + inkscape:window-x="0" + inkscape:window-y="36" + inkscape:window-maximized="1" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Calque 1" + inkscape:groupmode="layer" + id="layer1" + style="display:inline;filter:url(#filter6463)"> + <path + style="fill:#be6565;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.44099951;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 130.01379,128.08841 c 21.52877,0.022 43.05755,0.0441 64.58635,0.066 22.3643,-24.06221 48.52474,-31.460888 67.2259,-58.191769 2.71923,-0.06472 20.98912,-11.557161 33.93105,-24.068007 15.4842,-14.968435 25.95668,-31.394675 28.5419,-31.451169 50.54179,-1.104457 -14.12859,63.648811 -14.12859,63.648811 -4.32309,21.069986 25.52253,23.438544 42.33546,21.471776 42.70584,1.240658 85.40384,-0.8708 127.81819,-5.21873 25.73481,0.95872 51.31917,4.15799 76.90885,6.766478 9.54752,15.5434 0.83547,34.65487 -20.48439,28.40762 -26.2476,-2.99553 -27.63034,-2.30793 -53.8003,-2.02882 -12.78621,1.48832 -49.8581,9.73983 -62.64433,11.22817 -13.52493,16.3347 22.62946,13.21758 33.1675,10.07832 39.0413,-3.04219 77.95598,5.00291 116.9575,3.82945 23.10382,5.19727 8.0288,36.69047 -13.60972,28.74833 -44.19318,-2.94318 -88.36238,6.11604 -132.48254,0.88974 -19.82007,8.99739 21.64912,8.11335 30.86918,8.87517 27.68051,0.65118 54.70333,7.75945 82.5212,7.68297 22.55858,-7.69442 38.01639,26.96661 11.18339,29.72006 -36.46307,1.38329 -72.43925,-4.63303 -108.75088,-5.88757 -14.49857,0.76494 -17.71181,-4.22347 -30.32901,0.80137 -10.13989,10.28009 8.44125,11.49178 13.96391,12.36504 16.24581,9.74748 43.72122,2.97051 59.96588,18.47736 6.7707,13.90543 -22.57952,14.89139 -37.10486,9.32981 -30.11101,-5.44137 -35.65502,-1.94584 -60.67011,-9.04294 -19.50206,-3.53729 -40.83637,-3.42785 -60.71049,-0.67171 -24.72427,1.38733 -39.52595,0.63872 -62.90978,-7.17843 -35.40447,-1.67908 -63.45037,-6.42784 -94.2085,-0.57775 L 144.76,253.13224 Z" + id="path6341" + inkscape:connector-curvature="0" + inkscape:export-filename="/home/flo/test.png" + inkscape:export-xdpi="127.06" + inkscape:export-ydpi="127.06" + sodipodi:nodetypes="cccssccccccccccccccccccccccccc" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:0%;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';letter-spacing:-9.01962376px;word-spacing:0px;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:7.52591181;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + x="84.118187" + y="241.26474" + id="text4136" + transform="scale(1.133983,0.88184743)" + inkscape:export-filename="/home/flo/test.png" + inkscape:export-xdpi="127.06" + inkscape:export-ydpi="127.06"><tspan + sodipodi:role="line" + id="tspan4138" + x="84.118187" + y="241.26474" + style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:137.36247253px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';letter-spacing:-9.01962376px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:7.52591181;stroke-opacity:1">REVIL</tspan></text> + </g> +</svg> diff --git a/data/revil.xml b/data/revil.xml new file mode 100644 index 0000000..b7a00b3 --- /dev/null +++ b/data/revil.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<mime-type xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="application/revil"> + <glob pattern="*.rev"/> +</mime-type> diff --git a/src/Reveal.cpp b/src/Reveal.cpp new file mode 100644 index 0000000..68396b4 --- /dev/null +++ b/src/Reveal.cpp @@ -0,0 +1,718 @@ +/*************************************************************************** + * Reveal.cpp + * Part of Revil + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "Reveal.hpp" + +#include <iostream> +#include <unistd.h> +#include <FL/filename.H> + +#include <OpenNI.h> + +#include "geoms/BoxGeometry.hpp" +#include "geoms/CamGeometry.hpp" +#include "geoms/QuadGeometry.hpp" +#include "geoms/SphereGeometry.hpp" +#include "geoms/TubeGeometry.hpp" +#include "geoms/ConeGeometry.hpp" +#include "geoms/FrameGeometry.hpp" + +#include "modules/RevealedShapeModule.hpp" +#include "modules/RevealedPathModule.hpp" +#include "modules/RevealedTextModule.hpp" +#include "modules/RevealedCutModule.hpp" +#include "modules/RevealedArrowModule.hpp" +#include "modules/RevealedGridModule.hpp" +#include "modules/RevealedModelModule.hpp" +#include "modules/GroupModule.hpp" +#include "modules/SpaceModule.hpp" +#include "modules/PreviewModule.hpp" +#include "modules/ProjectorModule.hpp" +#include "modules/DepthCamModule.hpp" +#include "modules/DepthShapeModule.hpp" +#include "modules/DepthMeshModule.hpp" +#include "modules/DepthGroupModule.hpp" +#include "modules/RootSceneGroupModule.hpp" +#include "modules/SceneGroupModule.hpp" +#include "modules/OutputManagerModule.hpp" +#include "gui/MainWindow.hpp" +#include "gui/GuiListener.hpp" +#include "osc/OscManager.hpp" +#include "osc/OscListener.hpp" + +using namespace std; + +Reveal* Reveal::getInstance() { + static Reveal rev; + return &rev; +} + +Reveal::~Reveal(){} + +Reveal::Reveal() : GroupModule() { + m_type="Revil"; + m_name="revil"; + addAttribute(new Attribute("open", + Attribute::FILE_OPEN_ATTRIBUTE, + openCallback, this, Attribute::LOCAL, + false)); + addAttribute(new Attribute("save", + Attribute::FILE_SAVE_ATTRIBUTE, + saveCallback, this, Attribute::LOCAL, + false)); + addAttribute(new Attribute("quit", + Attribute::ACTION_ATTRIBUTE, + quitCallback, this, Attribute::LOCAL, + false)); + addAttribute(new Attribute("ressources_folder", + Attribute::FOLDER_OPEN_ATTRIBUTE, + ressourcesCallback, this, Attribute::LOCAL, + false)); + addAttribute(new Attribute("ressource_upload", + Attribute::ACTION_STRING_ATTRIBUTE, + uploadCallback,this,2,Attribute::GLOBAL,false)); + addAttribute(new Attribute("debug_osc_input", + Attribute::BOOL_ATTRIBUTE, + debugOscCallback,this,1,Attribute::GLOBAL)); + m_debugOSC=false; +} + +void idleFunc(void* data) { + Reveal::getInstance()->update(); + usleep(1000); +} + +void Reveal::init() { + m_openPlanned=0; + + //initialize osc input + OscManager::getInstance()->init(); + + //initialize depth cameras + openni::OpenNI::initialize(); + openni::OpenNI::setLogConsoleOutput(false); + cout<<"Initialized OpenNI "<<openni::OpenNI::getExtendedError()<<endl; + + //initialize observers counter + m_upObsIdCounter=0; + + //create all scene geometries + m_geomsMap[GEOM_BOX] = new BoxGeometry(); + m_geomsMap[GEOM_QUAD] = new QuadGeometry(); + m_geomsMap[GEOM_SPHERE] = new SphereGeometry(); + m_geomsMap[GEOM_TUBE] = new TubeGeometry(); + m_geomsMap[GEOM_CONE] = new ConeGeometry(); + m_geomsMap[GEOM_FRAME] = new FrameGeometry(); + map<GEOM_ID, Geometry*>::iterator itGeom = m_geomsMap.begin(); + for(; itGeom!=m_geomsMap.end(); ++itGeom) { + itGeom->second->setGeomID(itGeom->first); + m_geoms.push_back(itGeom->second); + } + + m_contextHandlersCounter=0; + + m_maxNbRevealed=502; + m_maxNbDepthCams=10; + + //add the outputs module + m_output = new OutputManagerModule(); + addChild(m_output); + + //add spaces module + m_spaces = new SpacesModule(); + addChild(m_spaces); + + //create scene module + m_scene = new RootSceneGroupModule(); + m_scene->addGroupAttributes(); + addChild(m_scene); + + //Initialize main window + fl_register_images(); + MainWindow::getInstance()->init(); + Fl::add_idle(idleFunc, MainWindow::getInstance()); + + //Initialize glfw for preview and projector windows + glewExperimental = GL_TRUE; + if(!glfwInit()) { + exit(EXIT_FAILURE); + } + glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); //FIXME GLFW 3.3 + glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); + glfwWindowHint(GLFW_AUTO_ICONIFY, GL_FALSE); +#ifdef GL42 + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); +#else + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); +#endif +#ifdef OSX + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); +#endif + + //add preview module + m_preview = new PreviewModule(); + m_spaces->addChild(m_preview); + + refreshModules(); + + //Show main window + MainWindow::getInstance()->show(); + + //start timer + gettimeofday(&m_prevTime, NULL); +} + +GLFWwindow* Reveal::getPreviewWindow() { + return m_preview->getWindow(); +} + +void Reveal::planOpen(std::string opSt) { + //FIXME find better strategy for delaying text + m_openPlanned=10; + m_openPlannedName=opSt; +} + +void Reveal::update() { + //delete listeners, attributes and modules + testDelete(); + + //update osc manager + OscManager::getInstance()->update(); + + //FIXME distinguish between anim and update (cam) + //update observers every 50ms + timeval curTime, timeDiff; + gettimeofday(&curTime,NULL); + timersub(&curTime, &m_prevTime, &timeDiff); + int timeDiffMs = timeDiff.tv_sec*1000.0+timeDiff.tv_usec/1000.0; + m_prevTime=curTime; + vector<Module*>::iterator itUp = m_updateObservers.begin(); + for(; itUp!=m_updateObservers.end(); ++itUp) { + (*itUp)->update(timeDiffMs); + } + + //draw all spaces + m_spaces->draw(); + + //delayed open to fix text rendering issues ... + if(m_openPlanned>0) { + m_openPlanned--; + if(m_openPlanned==0) { + open(m_openPlannedName); + } + } + + glfwPollEvents(); +} + +int Reveal::run() { + return Fl::run(); +} + +void Reveal::askQuit() { + MainWindow::getInstance()->cbQuit(); +} + +void Reveal::quit() { + glfwTerminate(); + exit(0); +} + +void Reveal::open(const std::string& fileName) { + cout<<"Opening "<<fileName<<endl; + bool open=true; + xmlDocPtr doc = xmlReadFile(fileName.c_str(), NULL, 0); + xmlNodePtr rootNode = xmlDocGetRootElement(doc); + if(doc==NULL || rootNode==NULL) { + DEBUG("Could not open file "<<fileName); + open=false; + } + else if(xmlStrcmp(rootNode->name, (const xmlChar*)"Revil")) { + xmlFreeDoc(doc); + DEBUG("Could not open file "<<fileName); + open=false; + } + if(open) { //if the file is valid + m_currentFile=fileName; + //clear the scene and spaces + m_scene->deleteChildren(); + m_spaces->removeChild(m_preview); + m_spaces->deleteChildren(); + m_spaces->addChild(m_preview); + m_revealedMap.clear(); + m_registeredOutputRevealed.clear(); + m_registeredOutputDepthCams.clear(); + m_upObsIdCounter=0; + m_updateObservers.clear(); + //and load + load(rootNode); + m_attributesMap["save"]->initFile(m_currentFile); + MainWindow::getInstance()->refreshModules(); + DEBUG("Opened file "<<fileName); + } +} + +void Reveal::save(const std::string& fileName) { + cout<<"Saving to "<<fileName<<endl; + m_currentFile=fileName; + xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); + xmlNodePtr rootNode = GroupModule::save(NULL); + xmlDocSetRootElement(doc, rootNode); + xmlSaveFormatFileEnc(fileName.c_str(), doc, "UTF-8", 1); + xmlFreeDoc(doc); + xmlCleanupParser(); +} + +void Reveal::setRessourcesFolder(const std::string& f) { + +} + +void Reveal::uploadRessource(const std::vector<std::string>& vf) { + +} + +void Reveal::load(xmlNodePtr node) { + Module::load(node); + xmlNodePtr modsNode; + for(modsNode=node->children; modsNode; modsNode=modsNode->next){ + if(modsNode->type == XML_ELEMENT_NODE && + !xmlStrcmp(modsNode->name, (const xmlChar *) "Modules")) { + xmlNodePtr modNode; + for(modNode=modsNode->children; modNode; modNode=modNode->next){ + if(modNode->type == XML_ELEMENT_NODE) { + if(!xmlStrcmp(modNode->name,(const xmlChar *)"Scene")) { + m_scene->load(modNode); + } + else if(!xmlStrcmp(modNode->name,(const xmlChar*)"Spaces")){ + m_spaces->load(modNode); + } + } + } + } + } +} + +Module* Reveal::createModule(const std::string& typeStr) { + Module* mod=NULL; + if(typeStr.compare("Projector")==0) { + mod=new ProjectorModule(); + } + else if(typeStr.compare("Space")==0) { + mod=new SpaceModule(); + } + else if(typeStr.compare("DepthGroup")==0) { + mod=new DepthGroupModule(); + } + else if(typeStr.compare("DepthCam")==0) { + mod=new DepthCamModule(); + } + else if(typeStr.compare("DepthShape")==0) { + mod=new DepthShapeModule(); + } + else if(typeStr.compare("DepthMesh")==0) { + mod=new DepthMeshModule(); + } + else if(typeStr.compare("SceneGroup")==0) { + mod=new SceneGroupModule(); + } + else if(typeStr.compare("Shape")==0) { + mod=new RevealedShapeModule(); + } + else if(typeStr.compare("Model")==0) { + mod=new RevealedModelModule(); + } + else if(typeStr.compare("Path")==0) { + mod=new RevealedPathModule(); + } + else if(typeStr.compare("Text")==0) { + mod=new RevealedTextModule(); + } + else if(typeStr.compare("Cut")==0) { + mod=new RevealedCutModule(); + } + else if(typeStr.compare("Arrow")==0) { + mod=new RevealedArrowModule(); + } + else if(typeStr.compare("Grid")==0) { + mod=new RevealedGridModule(); + } + return mod; +} + +Listener* Reveal::createListener(const std::string& typeStr) { + Listener* lis=NULL; + if(typeStr.compare("OscListener")==0) { + lis=new OscListener(); + } + return lis; +} + +int Reveal::getVisibilityMask(const std::string& visibleFrom) { + int res=0; + map<string, int>::iterator itVis = m_visibleFromMap.find(visibleFrom); + if(itVis!=m_visibleFromMap.end()) { + res=itVis->second; + } + return res; +} + +void Reveal::addUpdateObserver(Module* upObs) { + m_updateObservers.push_back(upObs); + upObs->setUpID(m_upObsIdCounter); + m_upObsIdCounter++; +} + +void Reveal::removeUpdateObserver(Module* upObs) { + vector<Module*>::iterator itObs = m_updateObservers.begin(); + for(; itObs!=m_updateObservers.end(); ) { + if((*itObs)->getUpID()==upObs->getUpID()) { + itObs = m_updateObservers.erase(itObs); + } + else { + itObs++; + } + } +} + +void Reveal::addModuleListObserver(ModuleListObserver* obs) { + unsigned int obsID=0; + while(m_moduleListObservers.find(obsID)!=m_moduleListObservers.end()) { + obsID++; + } + m_moduleListObservers[obsID]=obs; + obs->setModuleListObsID(obsID); +} + +void Reveal::removeModuleListObserver(ModuleListObserver* obs) { + m_moduleListObservers.erase(obs->getModuleListObsID()); +} + +void Reveal::addContextHandler(ContextHandler* cont) { + m_contextHandlers[m_contextHandlersCounter]=cont; + cont->setContextHandlerID(m_contextHandlersCounter); + m_contextHandlersCounter++; +} + +void Reveal::removeContextHandler(ContextHandler* cont) { + m_contextHandlers.erase(cont->getContextHandlerID()); +} + +void Reveal::registerGeom(Geometry* geom) { + GEOM_ID newID = GEOM_MODEL; + while(m_geomsMap.find(newID)!=m_geomsMap.end()) { + newID = GEOM_ID(int(newID)+1); + } + geom->setGeomID(newID); + m_geomsMap[newID]=geom; + m_geoms.push_back(geom); +} + +void Reveal::unregisterGeom(Geometry* geom) { + m_geomsMap.erase(geom->getGeomID()); + vector<Geometry*>::iterator itGeom = m_geoms.begin(); + for(; itGeom!=m_geoms.end(); ) { + if((*itGeom)->getGeomID()==geom->getGeomID()) { + itGeom = m_geoms.erase(itGeom); + } + else { + ++itGeom; + } + } +} + +void Reveal::registerRevealed(RevealedModule* rev) { + m_revealedVec.push_back(rev); + updateRevealed(); +} + +void Reveal::unregisterRevealed(RevealedModule* rev) { + vector<RevealedModule*>::iterator itRev=m_revealedVec.begin(); + for(; itRev!=m_revealedVec.end();) { + if((*itRev)->getRevID()==rev->getRevID()) { + itRev=m_revealedVec.erase(itRev); + } + else { + ++itRev; + } + } + updateRevealed(); + unregisterOutputRevealed(rev); +} + +void Reveal::updateRevealed() { + m_revealedMap.clear(); + vector<RevealedModule*>::iterator itRev=m_revealedVec.begin(); + unsigned int id=1; + for(; itRev!=m_revealedVec.end(); ++itRev, ++id) { + (*itRev)->setRevID(id); + m_revealedMap[id]=*itRev; + } +} + +void Reveal::refreshModules() { + //recreate map of modules and attributes + m_modulesMap.clear(); + m_fullAttributesMap.clear(); + GroupModule::listModulesAndAttributes("", m_modulesMap, + m_fullAttributesMap); + + //inform observers of the new module list + map<unsigned int, ModuleListObserver*>::iterator itObs + = m_moduleListObservers.begin(); + for(; itObs!=m_moduleListObservers.end(); ++itObs) { + itObs->second->updateModulesList(m_modulesMap); + } + + //refresh space/projectors list + m_visibleFromVec.clear(); + m_visibleFromMap.clear(); + m_visibleFromVec.push_back("none"); + m_visibleFromMap[m_visibleFromVec.back()]=VISIBLE_FROM_NONE; + m_visibleFromVec.push_back("all"); + m_visibleFromMap[m_visibleFromVec.back()]=VISIBLE_FROM_ALL; + m_spaces->getVisibleFromList(m_visibleFromVec, m_visibleFromMap); + + map<unsigned int, RevealedModule*>::iterator itMod + = m_revealedMap.begin(); + for(; itMod!=m_revealedMap.end(); ++itMod) { + itMod->second->setVisibleFromList(m_visibleFromVec); + } + + //refresh display + MainWindow::getInstance()->refreshModules(); + + /* + //TEMP list all attributes of all modules + map<string, Attribute*>::iterator itAtt = m_attributesMap.begin(); + for(;itAtt!=m_attributesMap.end(); ++itAtt) { + cout<<itAtt->first<<endl; + } + */ +} + +Attribute* Reveal::findAttribute(const std::string& fullName) { + map<string,Attribute*>::iterator itAtt = m_fullAttributesMap.find(fullName); + if(itAtt!=m_fullAttributesMap.end()) { + return itAtt->second; + } + return NULL; +} + +Module* Reveal::findModule(const std::string& fullName) { + map<string, Module*>::iterator itMod = m_modulesMap.find(fullName); + if(itMod!=m_modulesMap.end()) { + return itMod->second; + } + return NULL; +} + +void Reveal::registerOutputRevealed(RevealedModule* rev) { + bool found=false; + vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin(); + for(; itSh!=m_registeredOutputRevealed.end(); ++itSh) { + if((*itSh)->getRevID()==rev->getRevID()) { + found=true; + } + } + if(!found) { + m_registeredOutputRevealed.push_back(rev); + } + updateOutputRevealed(); +} + +void Reveal::unregisterOutputRevealed(RevealedModule* rev) { + + //remove it from list + vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin(); + for(; itSh!=m_registeredOutputRevealed.end(); ) { + if((*itSh)->getRevID()==rev->getRevID()) { + itSh=m_registeredOutputRevealed.erase(itSh); + } + else { + ++itSh; + } + } + + //reset offsets + updateOutputRevealed(); +} + +void Reveal::updateOutputRevealed() { + vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin(); + unsigned int offset=0; + for(; itSh!=m_registeredOutputRevealed.end(); ++itSh) { + (*itSh)->updateRevOffset(offset); + } +} + +void Reveal::registerOutputDepthCam(DepthCamModule* cam) { + bool found=false; + vector<DepthCamModule*>::iterator itCa=m_registeredOutputDepthCams.begin(); + for(; itCa!=m_registeredOutputDepthCams.end(); ++itCa) { + if((*itCa)->getDepthID()==cam->getDepthID()) { + found=true; + } + } + if(!found) { + m_registeredOutputDepthCams.push_back(cam); + } +} + +void Reveal::unregisterOutputDepthCam(DepthCamModule* cam) { + vector<DepthCamModule*>::iterator itCa=m_registeredOutputDepthCams.begin(); + for(; itCa!=m_registeredOutputDepthCams.end(); ) { + if((*itCa)->getDepthID()==cam->getDepthID()) { + itCa=m_registeredOutputDepthCams.erase(itCa); + } + else { + ++itCa; + } + } +} + +void Reveal::deleteListener(Listener* lis) { + m_listenersDeleteVec.push_back(lis); +} + +void Reveal::deleteModule(Module* mod) { + m_modulesDeleteVec.push_back(mod); + refreshModules(); +} + +void Reveal::testDelete() { + bool erasedListeners=false; + vector<Listener*>::iterator itLis = m_listenersDeleteVec.begin(); + for(; itLis!=m_listenersDeleteVec.end(); ++itLis) { + delete (*itLis); + erasedListeners=true; + } + m_listenersDeleteVec.clear(); + + if(m_modulesDeleteVec.size()>0) { + MainWindow::getInstance()->refreshModules(true, erasedListeners); + } + vector<Module*>::iterator itMod = m_modulesDeleteVec.begin(); + for(; itMod!=m_modulesDeleteVec.end(); ++itMod) { + delete (*itMod); + } + m_modulesDeleteVec.clear(); +} + +GLuint Reveal::createProgram(const char* vertSource, const char* fragSource) { + GLint compile_ok = GL_FALSE, link_ok = GL_FALSE; + GLuint vertexShader, fragmentShader; + vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vertSource, NULL); + glCompileShader(vertexShader); + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compile_ok); + if(!compile_ok) { + cout << "Error in vertex shader" << endl; + GLint maxLength = 0; + glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength); + std::vector<GLchar> errorLog(maxLength); + glGetShaderInfoLog(vertexShader,maxLength,&maxLength, &errorLog[0]); + vector<GLchar>::iterator itC=errorLog.begin(); + for(; itC!=errorLog.end(); ++itC) { + cout<<*itC; + } + cout<<endl; + } + fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fragSource, NULL); + glCompileShader(fragmentShader); + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compile_ok); + if(!compile_ok) { + cout << "Error in fragment shader" << endl; + GLint maxLength = 0; + glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); + std::vector<GLchar> errorLog(maxLength); + glGetShaderInfoLog(fragmentShader,maxLength,&maxLength, &errorLog[0]); + vector<GLchar>::iterator itC=errorLog.begin(); + for(; itC!=errorLog.end(); ++itC) { + cout<<*itC; + } + cout<<endl; + } + GLuint program = glCreateProgram(); + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + glLinkProgram(program); + glGetProgramiv(program, GL_LINK_STATUS, &link_ok); + if(!link_ok) { + cout<<"Error linking glsl program "<<program<<" "<<endl; + GLint maxLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + std::vector<GLchar> errorLog(maxLength); + glGetProgramInfoLog(program,maxLength,&maxLength, &errorLog[0]); + vector<GLchar>::iterator itC=errorLog.begin(); + for(; itC!=errorLog.end(); ++itC) { + cout<<*itC; + } + cout<<endl; + } + return program; +} + +void Reveal::measureStart() { + gettimeofday(&m_measureTime, NULL); + m_measuring=true; +} + +void Reveal::measureStore(const int& nbPixels) { + if(m_measuring) { + timeval curTime, timeDiff; + gettimeofday(&curTime, NULL); + timersub(&curTime, &m_measureTime, &timeDiff); + int timeDiffMs=int(timeDiff.tv_sec)*1000000 + + int(timeDiff.tv_usec); + if(m_measurePixelNb.find(nbPixels)==m_measurePixelNb.end()) { + m_measurePixelTimes[nbPixels]=0; + m_measurePixelNb[nbPixels]=0; + } + m_measurePixelNb[nbPixels]++; + m_measurePixelTimes[nbPixels]+=timeDiffMs; + cout<<nbPixels<<" " + <<float(m_measurePixelTimes[nbPixels]) + / float(m_measurePixelNb[nbPixels])<<endl; + + m_measuring=false; + } +} + +//MAIN +int main( int argc, char **argv ) { + Reveal::getInstance()->init(); + if(argc>1) { + char* abs = new char[200]; + fl_filename_absolute(abs, 200, argv[1]); + Reveal::getInstance()->planOpen(string(abs)); + } + return Reveal::getInstance()->run(); +} + + diff --git a/src/Reveal.hpp b/src/Reveal.hpp new file mode 100644 index 0000000..e1cf895 --- /dev/null +++ b/src/Reveal.hpp @@ -0,0 +1,272 @@ +/*************************************************************************** + * Reveal.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef Reveal_h +#define Reveal_h + +#include "modules/ContextHandler.hpp" +#include "modules/GroupModule.hpp" + +class DepthCamModule; +class ProjectorsModule; +class SceneModule; +class RootSceneGroupModule; +class RevealedModule; +class SpacesModule; +class OutputManagerModule; +class PreviewModule; + +class Geometry; +class ModuleListObserver; + +class Reveal : public GroupModule { + + public: + enum REVIL_PROGRAM { + PREVIEWPROG, SLICEPROG, SELECTPROG, RENDERPROG, CALIBPROG, POSTPROG + }; + enum REVIL_UNIFORM { + VIEWMAT, VIEWPROJMAT, MODELMAT, INVMODELMAT, MIRRORED, MODELSCALE, + SUBSHAPEINVMAT, + VIEWPORTWIDTH, VIEWPORTHEIGHT, + SHAPECOLOR, SHAPEID, SHAPEIDBIT, SUBSHAPEID, SUBSHAPESNB, + SHAPEGEOM, + + SURFACE, SURFACECOLOR, SURFACETHICKNESS, + + INSIDEVISIBLE, INSIDESTRUCT, STRUCTRATIO, + GRADIENTALPHA, GRADIENTTYPE, GRADIENTSTEPS, GRADIENTCURVERATIO, + GRADIENTTEXTURE, + DENSITYALPHA, DENSITYTYPE, DENSITYRATIO, DENSITYSIZE, + DENSITYCURVERATIO, + TEXALPHA, TEXBLEND, TEXOFFSET, TEXSCALE, TEXGRAY, + REACTIVITY, + + BBOXMIN, BBOXSIZE, BBOXROT, BBOXLOCALSIZE, + + REVSIZE, REVSURFACE, REVINSIDE, REVCENTER, + REVCURSOR, REVCOLOR, REVHISTO, REVVOXELS, REVEALEDBY, + OUTSHAPESIZE, OUTHISTOSIZE, OUTVOXELSIZE, OUTDEPTHSIZE, OUTNBDEPTH, + BRECT, + OUTPUTTEX, SLICETEX, SELECTTEX, INSIDETEX, SURFACETEX, COORDSTEX, + REACTTEX, SURFDISTEX, + CAMTEX, CAMTEXFIL, CAMXRESO, CAMYRESO, CAMXZFACTOR, CAMYZFACTOR, + CAMFILTER, CAMFLIP, CAMCONTOURTHRESH, + CAMMARKERS, MARKTEX, BACKGROUND, + DEPTHTYPE, DEPTHID, OUTPUTCURS, + PATW, PATPOSX, PATPOSY, PATNBX, PATNBY, PATBRIGHT, PATTERNTEX, + PATRANGE, PATOFFSET, + POSTFILTER, RENDERTEX + }; + + enum GEOM_ID { + GEOM_BOX, GEOM_SPHERE, GEOM_TUBE, GEOM_CONE, GEOM_FRAME, + GEOM_PATH, GEOM_QUAD, + GEOM_CAM1280, GEOM_CAM640, GEOM_CAM320, + GEOM_MODEL + }; + + enum VISIBLE_FROM { + VISIBLE_FROM_NONE, VISIBLE_FROM_ALL + }; + + public: + static Reveal* getInstance(); + ~Reveal(); + + void init(); + int run(); + void update(); + void planOpen(std::string); + + void initPrograms(); + + static void openCallback(Module* mod, const std::string& f) { + dynamic_cast<Reveal*>(mod)->open(f); + } + void open(const std::string& f); + static void saveCallback(Module* mod, const std::string& f) { + dynamic_cast<Reveal*>(mod)->save(f); + } + void save(const std::string& f); + static void quitCallback(Module* mod) { + dynamic_cast<Reveal*>(mod)->askQuit(); + } + void askQuit(); + void quit(); + + static void ressourcesCallback(Module* mod, const std::string& f) { + dynamic_cast<Reveal*>(mod)->setRessourcesFolder(f); + } + void setRessourcesFolder(const std::string& f); + static void uploadCallback(Module* mod, + const std::vector<std::string>& vf + ) { + dynamic_cast<Reveal*>(mod)->uploadRessource(vf); + } + void uploadRessource(const std::vector<std::string>& vf); + static void debugOscCallback(Module* mod, + const std::vector<bool>& vf + ) { + dynamic_cast<Reveal*>(mod)->debugOSC(vf[0]); + } + void debugOSC(const bool& deb){m_debugOSC=deb;} + const bool& getDebugOSC() {return m_debugOSC;} + + virtual void load(xmlNodePtr); + + void addUpdateObserver(Module* upObs); + void removeUpdateObserver(Module* upObs); + + void refreshModules(); + Module* createModule(const std::string& typeStr); + Module* findModule(const std::string& fullName); + Attribute* findAttribute(const std::string& fullName); + + int getVisibilityMask(const std::string& visibleFrom); + + Listener* createListener(const std::string& typeStr); + + inline SpacesModule* getSpaces(){return m_spaces;} + + //Revealed modules + void registerRevealed(RevealedModule*); + void unregisterRevealed(RevealedModule*); + RevealedModule* getRevealedModule(const unsigned int& s) { + if(m_revealedMap.find(s)!=m_revealedMap.end()) { + return m_revealedMap[s]; + } + return NULL; + } + unsigned int getNbRevealed(){return m_revealedVec.size();} + inline const int& getMaxNbRevealed(){return m_maxNbRevealed;} + void updateRevealed(); + + void registerOutputRevealed(RevealedModule* rev); + void unregisterOutputRevealed(RevealedModule* rev); + inline std::vector<RevealedModule*>& editRegisteredOutputRevealed() { + return m_registeredOutputRevealed; + } + void updateOutputRevealed(); + + inline const int& getMaxNbDepthCams(){return m_maxNbDepthCams;} + void registerOutputDepthCam(DepthCamModule* cam); + void unregisterOutputDepthCam(DepthCamModule* cam); + inline std::vector<DepthCamModule*>& editRegisteredOutputDepthCams() { + return m_registeredOutputDepthCams; + } + + //removing things + void deleteListener(Listener*); + void deleteModule(Module*); + + //Geometries + const std::vector<Geometry*>& getGeoms(){return m_geoms;} + Geometry* getGeom(const GEOM_ID& geomStr) { + return m_geomsMap[geomStr]; + } + void registerGeom(Geometry* geom); + void unregisterGeom(Geometry* geom); + + void addModuleListObserver(ModuleListObserver* obs); + void removeModuleListObserver(ModuleListObserver* obs); + + void addContextHandler(ContextHandler* cont); + void removeContextHandler(ContextHandler* cont); + inline ContextHandler* getContextHandler(const int& id) { + return m_contextHandlers[id]; + } + + GLuint createProgram(const char* vertSource, const char* fragSource); + + GLFWwindow* getPreviewWindow(); + + void measureStart(); + void measureStore(const int& nbPixels); + const std::string& getCurrentFile(){return m_currentFile;} + + private: + Reveal(); + void testDelete(); + + private: + SpacesModule* m_spaces; + RootSceneGroupModule* m_scene; + PreviewModule* m_preview; + OutputManagerModule* m_output; + bool m_debugOSC; + + int m_openPlanned; + std::string m_openPlannedName; + std::string m_currentFile; + + std::map<std::string, Module*> m_typesMap; + + std::vector<Module*> m_updateObservers; + unsigned int m_upObsIdCounter; + timeval m_prevTime; + + std::map<std::string, Module*> m_modulesMap; + std::map<std::string, Attribute*> m_fullAttributesMap; + std::map<unsigned int, ModuleListObserver*> m_moduleListObservers; + + std::map<GEOM_ID, Geometry*> m_geomsMap; + std::vector<Geometry*> m_geoms; + + std::map<std::string, int> m_visibleFromMap; + std::vector<std::string> m_visibleFromVec; + + int m_contextHandlersCounter; + std::map<unsigned int, ContextHandler*> m_contextHandlers; + + std::vector<RevealedModule*> m_revealedVec; + std::map<unsigned int, RevealedModule*> m_revealedMap; + int m_maxNbRevealed; + std::vector<RevealedModule*> m_registeredOutputRevealed; + int m_maxNbDepthCams; + std::vector<DepthCamModule*> m_registeredOutputDepthCams; + std::vector<Listener*> m_listenersDeleteVec; + std::vector<Attribute*> m_attributesDeleteVec; + std::vector<Module*> m_modulesDeleteVec; + + + timeval m_measureTime; + bool m_measuring; + std::map<int, int> m_measurePixelTimes; + std::map<int, int> m_measurePixelNb; +}; + +class ModuleListObserver { + public: + virtual ~ModuleListObserver(){} + virtual void updateModulesList(const std::map<std::string, Module*>&)=0; + void setModuleListObsID(const unsigned int& id){m_moduleListObsID=id;} + const unsigned int& getModuleListObsID(){return m_moduleListObsID;} + + protected: + unsigned int m_moduleListObsID; + +}; + +#endif + diff --git a/src/audio/AudioManager.hpp b/src/audio/AudioManager.hpp new file mode 100644 index 0000000..ead8896 --- /dev/null +++ b/src/audio/AudioManager.hpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * AudioManager.hpp + * Part of Revil + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <portaudio.h> + + +#ifndef OscManager_h +#define OscManager_h + +class AudioManager { + public: + static AudioManager* getInstance(); + ~AudioManager(); + + + private: + AudioManager(){} + +} + +#endif + diff --git a/src/geoms/BoxGeometry.cpp b/src/geoms/BoxGeometry.cpp new file mode 100644 index 0000000..fd56f5a --- /dev/null +++ b/src/geoms/BoxGeometry.cpp @@ -0,0 +1,116 @@ +/*************************************************************************** + * BoxGeometry.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "BoxGeometry.hpp" + +using namespace std; + +BoxGeometry::BoxGeometry(): Geometry() { + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + + //front + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(2); + m_indexBufferData.push_back(3); + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(1); + m_indexBufferData.push_back(2); + //right + m_indexBufferData.push_back(1); + m_indexBufferData.push_back(5); + m_indexBufferData.push_back(6); + m_indexBufferData.push_back(1); + m_indexBufferData.push_back(6); + m_indexBufferData.push_back(2); + //back + m_indexBufferData.push_back(4); + m_indexBufferData.push_back(7); + m_indexBufferData.push_back(6); + m_indexBufferData.push_back(4); + m_indexBufferData.push_back(6); + m_indexBufferData.push_back(5); + //left + m_indexBufferData.push_back(7); + m_indexBufferData.push_back(4); + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(7); + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(3); + //top + m_indexBufferData.push_back(3); + m_indexBufferData.push_back(2); + m_indexBufferData.push_back(6); + m_indexBufferData.push_back(3); + m_indexBufferData.push_back(6); + m_indexBufferData.push_back(7); + //bottom + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(5); + m_indexBufferData.push_back(1); + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(4); + m_indexBufferData.push_back(5); + + m_compoSizes.push_back(m_indexBufferData.size()); +} + +BoxGeometry::~BoxGeometry() {} + diff --git a/src/geoms/BoxGeometry.hpp b/src/geoms/BoxGeometry.hpp new file mode 100644 index 0000000..423d487 --- /dev/null +++ b/src/geoms/BoxGeometry.hpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * BoxGeometry.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef BoxGeometry_h +#define BoxGeometry_h + +#include "Geometry.hpp" + +class BoxGeometry : public Geometry { + public: + BoxGeometry(); + virtual ~BoxGeometry(); + + protected: + +}; + +#endif diff --git a/src/geoms/CamGeometry.cpp b/src/geoms/CamGeometry.cpp new file mode 100644 index 0000000..2c18101 --- /dev/null +++ b/src/geoms/CamGeometry.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * CamGeometry.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "CamGeometry.hpp" + +using namespace std; + +CamGeometry::CamGeometry(const int& width, const int& height): Geometry() { + m_points=false; + setSize(width, height); +} + +CamGeometry::~CamGeometry() {} + +void CamGeometry::setSize(const int& width, const int& height) { + m_vertexBufferData.clear(); + m_indexBufferData.clear(); + m_compoSizes.clear(); + + for(int r=0; r<height; r++) { + for(int c=0; c<width; c++) { + m_vertexBufferData.push_back(GLfloat(c)); + m_vertexBufferData.push_back(GLfloat(r)); + m_vertexBufferData.push_back(10.0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + } + } + for(int r=0; r<height-1; r++) { + for(int c=0; c<width-1; c++) { + if(m_points) { + m_indexBufferData.push_back(width*r+c); + } + else { + m_indexBufferData.push_back(width*r+c); + m_indexBufferData.push_back(width*(r)+c+1); + m_indexBufferData.push_back(width*(r+1)+c); + + m_indexBufferData.push_back(width*(r+1)+c+1); + m_indexBufferData.push_back(width*(r+1)+c); + m_indexBufferData.push_back(width*(r)+c+1); + } + } + } + + m_compoSizes.push_back(m_indexBufferData.size()); + for(auto& cont : m_contexts) { + cont.second.m_refresh=true; + } +} + diff --git a/src/geoms/CamGeometry.hpp b/src/geoms/CamGeometry.hpp new file mode 100644 index 0000000..aaa89c4 --- /dev/null +++ b/src/geoms/CamGeometry.hpp @@ -0,0 +1,40 @@ +/*************************************************************************** + * CamGeometry.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef CamGeometry_h +#define CamGeometry_h + +#include "Geometry.hpp" + +class CamGeometry : public Geometry { + public: + CamGeometry(const int& width, const int& height); + virtual ~CamGeometry(); + + void setSize(const int & width, const int& height); + + protected: + +}; + +#endif diff --git a/src/geoms/ConeGeometry.cpp b/src/geoms/ConeGeometry.cpp new file mode 100644 index 0000000..cc521b9 --- /dev/null +++ b/src/geoms/ConeGeometry.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * ConeGeometry.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ConeGeometry.hpp" + +using namespace std; + +ConeGeometry::ConeGeometry(): Geometry() { + + int nbEdges=10; + int length=1; + + //add the vertices + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + float angle=0; + float angleStep=M_PI*2.0/float(nbEdges); + for(int v=0; v<nbEdges; ++v, angle+=angleStep) { + glm::vec4 pnt = glm::vec4(cos(angle)*length/2.0, + -0.5, + sin(angle)*length/2.0, + 1); + m_vertexBufferData.push_back(pnt[0]); + m_vertexBufferData.push_back(pnt[1]); + m_vertexBufferData.push_back(pnt[2]); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + } + + //indices + // sides + for(int v=1; v<nbEdges+1; ++v) { + m_indexBufferData.push_back(0); + m_indexBufferData.push_back((v+1<nbEdges+1)?v+1:1); + m_indexBufferData.push_back(v); + } + // bottom + for(int v=2; v<nbEdges; ++v) { + m_indexBufferData.push_back(1); + m_indexBufferData.push_back(v); + m_indexBufferData.push_back(v+1); + } + + + m_compoSizes.push_back(m_indexBufferData.size()); +} + +ConeGeometry::~ConeGeometry() {} + diff --git a/src/geoms/ConeGeometry.hpp b/src/geoms/ConeGeometry.hpp new file mode 100644 index 0000000..f95358f --- /dev/null +++ b/src/geoms/ConeGeometry.hpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * ConeGeometry.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef ConeGeometry_h +#define ConeGeometry_h + +#include "Geometry.hpp" + +class ConeGeometry : public Geometry { + public: + ConeGeometry(); + virtual ~ConeGeometry(); + + protected: + +}; + +#endif diff --git a/src/geoms/FrameGeometry.cpp b/src/geoms/FrameGeometry.cpp new file mode 100644 index 0000000..363becf --- /dev/null +++ b/src/geoms/FrameGeometry.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * FrameGeometry.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "FrameGeometry.hpp" + +using namespace std; + +FrameGeometry::FrameGeometry(): Geometry() { + + float inter=0.4; + for(float x=0; x<2; ++x) { + m_vertexBufferData.push_back(0.1*(x-0.5)); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(inter*2*(x-0.5)); + m_vertexBufferData.push_back(inter); + m_vertexBufferData.push_back(0.45); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(-0.5+x); + m_vertexBufferData.push_back(0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(inter*2*(x-0.5)); + m_vertexBufferData.push_back(inter); + m_vertexBufferData.push_back(-0.45); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + + m_vertexBufferData.push_back(0.1*(x-0.5)); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(inter*2*(x-0.5)); + m_vertexBufferData.push_back(-inter); + m_vertexBufferData.push_back(-0.45); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(-0.5+x); + m_vertexBufferData.push_back(-0.5); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(inter*2*(x-0.5)); + m_vertexBufferData.push_back(-inter); + m_vertexBufferData.push_back(0.45); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + } + + //around faces + for(int v=0; v<8; v++) { + if(v<7) { + m_indexBufferData.push_back(v%16); + m_indexBufferData.push_back((v+9)%16); + m_indexBufferData.push_back((v+1)%16); + } + m_indexBufferData.push_back(v%16); + m_indexBufferData.push_back((v+8)%16); + m_indexBufferData.push_back((v+9)%16); + } + + m_indexBufferData.push_back(15); + m_indexBufferData.push_back(8); + m_indexBufferData.push_back(0); + + + //extremities + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(1); + m_indexBufferData.push_back(7); + m_indexBufferData.push_back(8); + m_indexBufferData.push_back(15); + m_indexBufferData.push_back(9); + + m_indexBufferData.push_back(12); + m_indexBufferData.push_back(11); + m_indexBufferData.push_back(13); + m_indexBufferData.push_back(4); + m_indexBufferData.push_back(5); + m_indexBufferData.push_back(3); + + + //sides faces + for(int x=0; x<2; x++) { + m_indexBufferData.push_back(2+x*8); + m_indexBufferData.push_back((x==0)?7:1+x*8); + m_indexBufferData.push_back((x==0)?1:7+x*8); + + m_indexBufferData.push_back(2+x*8); + m_indexBufferData.push_back((x==0)?6:7+x*8); + m_indexBufferData.push_back((x==0)?7:6+x*8); + + m_indexBufferData.push_back(2+x*8); + m_indexBufferData.push_back((x==0)?5:6+x*8); + m_indexBufferData.push_back((x==0)?6:5+x*8); + + m_indexBufferData.push_back(2+x*8); + m_indexBufferData.push_back((x==0)?3:5+x*8); + m_indexBufferData.push_back((x==0)?5:3+x*8); + } + + + m_compoSizes.push_back(m_indexBufferData.size()); +} + +FrameGeometry::~FrameGeometry() {} + diff --git a/src/geoms/FrameGeometry.hpp b/src/geoms/FrameGeometry.hpp new file mode 100644 index 0000000..7902713 --- /dev/null +++ b/src/geoms/FrameGeometry.hpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * FrameGeometry.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef FrameGeometry_h +#define FrameGeometry_h + +#include "Geometry.hpp" + +class FrameGeometry : public Geometry { + public: + FrameGeometry(); + virtual ~FrameGeometry(); + + protected: + +}; + +#endif diff --git a/src/geoms/Geometry.cpp b/src/geoms/Geometry.cpp new file mode 100644 index 0000000..47a3841 --- /dev/null +++ b/src/geoms/Geometry.cpp @@ -0,0 +1,168 @@ +/*************************************************************************** + * Geometry.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "Geometry.hpp" +#include <iostream> + +using namespace std; + +Geometry::Geometry():m_hasTexCoords(false), m_points(false) { + m_geomID=(Reveal::GEOM_ID)-1; +} + +Geometry::~Geometry() {} + +void Geometry::draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const int& visibilityMask) { + + if(m_contexts.find(contextID)==m_contexts.end()) { + ContextGeometry& cont = m_contexts[contextID]; + cont.m_refresh=true; + glGenVertexArrays(1, &cont.m_vertexArrayID); + glBindVertexArray(cont.m_vertexArrayID); + glGenBuffers(1, &cont.m_vertexBuffer); + glGenBuffers(1, &cont.m_indexBuffer); + } + if(m_contexts[contextID].m_refresh) { + ContextGeometry& cont = m_contexts[contextID]; + glBindBuffer(GL_ARRAY_BUFFER, cont.m_vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, + m_vertexBufferData.size()*sizeof(GLfloat), + &m_vertexBufferData[0], GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cont.m_indexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + m_indexBufferData.size()*sizeof(GLuint), + &m_indexBufferData[0], GL_STATIC_DRAW); + cont.m_refresh=false; + } + + ContextGeometry& cont = m_contexts[contextID]; + + //load vertices + GLintptr posOff = 0; + GLintptr texOff = 3*sizeof(float); + GLsizei stride = 0; + glBindVertexArray(cont.m_vertexArrayID); + glBindBuffer(GL_ARRAY_BUFFER, cont.m_vertexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cont.m_indexBuffer); + + glEnableVertexAttribArray(0); + stride= 5*sizeof(float); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride,(GLvoid*)texOff); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)posOff); + + //draw geomodules attached to that geometry + vector<GeomModule*>::const_iterator itGeom=m_modules.begin(); + for(; itGeom!=m_modules.end(); ++itGeom) { + if((*itGeom)->isVisible() + && (((*itGeom)->getVisibilityMask() & visibilityMask) + || prog==Reveal::PREVIEWPROG )) { + //for each component + unsigned int start=0; + for(unsigned int c=0; c<m_compoSizes.size(); ++c) { + //load uniforms and model mat + (*itGeom)->draw(contextID, prog, uniforms, c); + //draw triangles + if(m_points) { + glDrawElements(GL_POINTS, m_compoSizes[c], + GL_UNSIGNED_INT,(GLvoid*)(start*sizeof(GLuint))); + } + else { + glDrawElements(GL_TRIANGLES, m_compoSizes[c], + GL_UNSIGNED_INT,(GLvoid*)(start*sizeof(GLuint))); + } + start+=m_compoSizes[c]; + } + } + } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); +} + +void Geometry::drawDirect(const int& contextID) { + if(m_contexts.find(contextID)==m_contexts.end()) { + ContextGeometry& cont = m_contexts[contextID]; + glGenVertexArrays(1, &cont.m_vertexArrayID); + glBindVertexArray(cont.m_vertexArrayID); + glGenBuffers(1, &cont.m_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, cont.m_vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, + m_vertexBufferData.size()*sizeof(GLfloat), + &m_vertexBufferData[0], GL_STATIC_DRAW); + glGenBuffers(1, &cont.m_indexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cont.m_indexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + m_indexBufferData.size()*sizeof(GLuint), + &m_indexBufferData[0], GL_STATIC_DRAW); + } + + ContextGeometry& cont = m_contexts[contextID]; + + //load vertices + glBindBuffer(GL_ARRAY_BUFFER, cont.m_vertexBuffer); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float),(void*)(3*sizeof(float))); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cont.m_indexBuffer); + + //draw triangles + glDrawElements(GL_TRIANGLES, m_indexBufferData.size(), + GL_UNSIGNED_INT, 0); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); +} + +void Geometry::registerModule(GeomModule* geom) { + unsigned int id=0; + while(m_modulesMap.find(id)!=m_modulesMap.end()) { + id++; + } + geom->setGeomID(id); + m_modulesMap[id]=geom; + m_modules.push_back(geom); +} + +void Geometry::unregisterModule(GeomModule* geom) { + m_modulesMap.erase(geom->getGeomID()); + vector<GeomModule*>::iterator itGeom=m_modules.begin(); + for(; itGeom!=m_modules.end();) { + if((*itGeom)->getGeomID()==geom->getGeomID()) { + itGeom=m_modules.erase(itGeom); + } + else { + ++itGeom; + } + } +} + +void Geometry::refresh() { + map<int, ContextGeometry>::iterator itCo=m_contexts.begin(); + for(; itCo!=m_contexts.end(); ++itCo) { + itCo->second.m_refresh=true; + } +} + diff --git a/src/geoms/Geometry.hpp b/src/geoms/Geometry.hpp new file mode 100644 index 0000000..4b52904 --- /dev/null +++ b/src/geoms/Geometry.hpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Geometry.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef Geometry_h +#define Geometry_h + +#include <glm/vec3.hpp> +#include <map> +#include <vector> + +#include "../modules/GeomModule.hpp" +#include "../Reveal.hpp" + +struct ContextGeometry { + GLuint m_vertexBuffer; + GLuint m_vertexArrayID; + GLuint m_indexBuffer; + bool m_refresh; +}; + +class Geometry { + public: + Geometry(); + virtual ~Geometry(); + virtual void draw(const int& contextID, + const Reveal::REVIL_PROGRAM&, + std::map<Reveal::REVIL_UNIFORM, GLint>&, + const int& visibilityMask); + virtual void drawDirect(const int& contextID); + + void registerModule(GeomModule*); + void unregisterModule(GeomModule*); + inline const std::vector<GeomModule*>& getModules(){return m_modules;} + + inline void setGeomID(const Reveal::GEOM_ID& id) {m_geomID=id;} + inline const Reveal::GEOM_ID& getGeomID() {return m_geomID;} + + std::vector<GLfloat>& editVertexBufferData(){return m_vertexBufferData;} + std::vector<GLuint>& editIndexBufferData(){return m_indexBufferData;} + std::vector<int>& editCompoSizes(){return m_compoSizes;} + void refresh(); + + void hasTexCoords(bool tc){m_hasTexCoords=tc;} + + protected: + Reveal::GEOM_ID m_geomID; + bool m_hasTexCoords; + bool m_points; + + std::vector<GeomModule*> m_modules; + std::map<unsigned int, GeomModule*> m_modulesMap; + + std::vector<GLfloat> m_vertexBufferData; + std::vector<GLuint> m_indexBufferData; + std::vector<int> m_compoSizes; + + std::map<int, ContextGeometry> m_contexts; +}; + +#endif diff --git a/src/geoms/QuadGeometry.cpp b/src/geoms/QuadGeometry.cpp new file mode 100644 index 0000000..469888a --- /dev/null +++ b/src/geoms/QuadGeometry.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * QuadGeometry.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "QuadGeometry.hpp" + +using namespace std; + +QuadGeometry::QuadGeometry(): Geometry() { + m_vertexBufferData.push_back(-1); + m_vertexBufferData.push_back(-1); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(1); + m_vertexBufferData.push_back(-1); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(1); + m_vertexBufferData.push_back(1); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(-1); + m_vertexBufferData.push_back(1); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(2); + m_indexBufferData.push_back(3); + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(1); + m_indexBufferData.push_back(2); + + m_compoSizes.push_back(m_indexBufferData.size()); +} + +QuadGeometry::~QuadGeometry() {} + diff --git a/src/geoms/QuadGeometry.hpp b/src/geoms/QuadGeometry.hpp new file mode 100644 index 0000000..3820bbc --- /dev/null +++ b/src/geoms/QuadGeometry.hpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * QuadGeometry.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef QuadGeometry_h +#define QuadGeometry_h + +#include "Geometry.hpp" + +class QuadGeometry : public Geometry { + public: + QuadGeometry(); + virtual ~QuadGeometry(); + + protected: + +}; + +#endif diff --git a/src/geoms/SphereGeometry.cpp b/src/geoms/SphereGeometry.cpp new file mode 100644 index 0000000..c38804d --- /dev/null +++ b/src/geoms/SphereGeometry.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * SphereGeometry.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "SphereGeometry.hpp" + +using namespace std; + +SphereGeometry::SphereGeometry(): Geometry() { + int nbHor=20; + int nbVert=10; + float rad=0.5; + float stepH = (M_PI*2.0/float(nbHor)); + float stepV = (M_PI/float(nbVert)); + + //top vertex + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(rad); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + //bottom vertex + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(-rad); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + + //other vertices and indices + for(int v=1; v<nbVert+1; ++v) { + float posY = rad*cos(float(v)*stepV); + float out = abs(rad * sin(float(v)*stepV)); + for(int h=0; h<nbHor; ++h) { + float angleH = float(h)*stepH; + m_vertexBufferData.push_back(out*cos(angleH)); + m_vertexBufferData.push_back(posY); + m_vertexBufferData.push_back(out*sin(angleH)); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + + if(v==nbVert) { //bottom row + m_indexBufferData.push_back(2+(v-1)*nbHor+h); + m_indexBufferData.push_back(2+(v-1)*nbHor+(h+1)%nbHor); + m_indexBufferData.push_back(1); + } + else {//other rows (2 triangles) + if(v==1) { //top row + m_indexBufferData.push_back(0); + m_indexBufferData.push_back(2+(v-1)*nbHor+(h+1)%nbHor); + m_indexBufferData.push_back(2+(v-1)*nbHor+h); + } + m_indexBufferData.push_back(2+(v-1)*nbHor+h); + m_indexBufferData.push_back(2+(v-1)*nbHor+(h+1)%nbHor); + m_indexBufferData.push_back(2+(v)*nbHor+(h+1)%nbHor); + + m_indexBufferData.push_back(2+(v-1)*nbHor+h); + m_indexBufferData.push_back(2+(v)*nbHor+(h+1)%nbHor); + m_indexBufferData.push_back(2+(v)*nbHor+h); + } + } + } + m_compoSizes.push_back(m_indexBufferData.size()); +} + +SphereGeometry::~SphereGeometry() {} + diff --git a/src/geoms/SphereGeometry.hpp b/src/geoms/SphereGeometry.hpp new file mode 100644 index 0000000..1d2c9ec --- /dev/null +++ b/src/geoms/SphereGeometry.hpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * SphereGeometry.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef SphereGeometry_h +#define SphereGeometry_h + +#include "Geometry.hpp" + +class SphereGeometry : public Geometry { + public: + SphereGeometry(); + virtual ~SphereGeometry(); + + protected: + +}; + +#endif diff --git a/src/geoms/TubeGeometry.cpp b/src/geoms/TubeGeometry.cpp new file mode 100644 index 0000000..4e34cec --- /dev/null +++ b/src/geoms/TubeGeometry.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + * TubeGeometry.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "TubeGeometry.hpp" + +using namespace std; + +TubeGeometry::TubeGeometry(): Geometry() { + + int nbEdges=10; + int length=1; + + //add the vertices + float angle=0; + float angleStep=M_PI*2.0/float(nbEdges); + for(int p=0; p<2; ++p) { + for(int v=0; v<nbEdges; ++v, angle+=angleStep) { + glm::vec4 pnt = glm::vec4(cos(angle)*length/2.0, + p*length-length/2.0, + sin(angle)*length/2.0, + 1); + m_vertexBufferData.push_back(pnt[0]); + m_vertexBufferData.push_back(pnt[1]); + m_vertexBufferData.push_back(pnt[2]); + m_vertexBufferData.push_back(0); + m_vertexBufferData.push_back(0); + } + } + + for(int v=0; v<nbEdges-2; ++v) { + m_indexBufferData.push_back(v); + m_indexBufferData.push_back(v+1); + m_indexBufferData.push_back(nbEdges-1); + } + for(int v=0; v<nbEdges; ++v) { + m_indexBufferData.push_back(v); + m_indexBufferData.push_back(nbEdges+v); + m_indexBufferData.push_back((v+1)%nbEdges); + + m_indexBufferData.push_back(nbEdges+v); + m_indexBufferData.push_back(nbEdges+(v+1)%nbEdges); + m_indexBufferData.push_back((v+1)%nbEdges); + } + for(int v=0; v<nbEdges-2; ++v) { + m_indexBufferData.push_back(nbEdges+v); + m_indexBufferData.push_back(nbEdges+nbEdges-1); + m_indexBufferData.push_back(nbEdges+v+1); + } + + m_compoSizes.push_back(m_indexBufferData.size()); +} + +TubeGeometry::~TubeGeometry() {} + diff --git a/src/geoms/TubeGeometry.hpp b/src/geoms/TubeGeometry.hpp new file mode 100644 index 0000000..ca76894 --- /dev/null +++ b/src/geoms/TubeGeometry.hpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * TubeGeometry.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef TubeGeometry_h +#define TubeGeometry_h + +#include "Geometry.hpp" + +class TubeGeometry : public Geometry { + public: + TubeGeometry(); + virtual ~TubeGeometry(); + + protected: + +}; + +#endif diff --git a/src/gui/AttributeWidget.cpp b/src/gui/AttributeWidget.cpp new file mode 100644 index 0000000..c942390 --- /dev/null +++ b/src/gui/AttributeWidget.cpp @@ -0,0 +1,517 @@ +/*************************************************************************** + * AttributeWidget.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "AttributeWidget.hpp" +#include <iostream> +#include <FL/fl_draw.H> +#include <FL/Fl.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Value_Input.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Native_File_Chooser.H> +#include <FL/filename.H> + +#include "../Reveal.hpp" +#include "MainWindow.hpp" +#include "ListenerWidget.hpp" +#include "GuiListener.hpp" + +using namespace std; + +AttributeWidget::AttributeWidget(int x, int y, + int w, int h, + Attribute* attribute):Fl_Group(x,y,w,h,""), + m_attribute(attribute) { + m_name = m_attribute->getName(); + m_fullName = m_attribute->getFullName(); + m_nbValues = m_attribute->getNbValues(); + label(m_name.c_str()); + align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + color(FL_SELECTION_COLOR); + box(FL_BORDER_BOX); + end(); + + + int margin=5; + //add widgets depending on type + if(m_nbValues<=4) { + switch(m_attribute->getType()) { + case Attribute::FLOAT_ATTRIBUTE : + case Attribute::ACTION_FLOAT_ATTRIBUTE : { + int inpWidth=50; + int pos=fl_width(m_name.c_str())+margin*2; + if(m_attribute->getType()==Attribute::ACTION_FLOAT_ATTRIBUTE) { + label(""); + m_button = new Fl_Button(x+margin*2, y+margin, + pos, h-2*margin, + m_name.c_str()); + pos+=margin*4; + m_button->callback(statAction, this); + m_button->box(FL_FLAT_BOX); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + m_button->deactivate(); + } + add(m_button); + } + for(unsigned int v=0; v<m_nbValues; ++v) { + Fl_Value_Input* adj = new Fl_Value_Input( + x+pos+(inpWidth+margin)*v, + y+margin, inpWidth, h-2*margin, + ""); + adj->step(0.1); + adj->bounds(-10000, 10000); + if(m_attribute->getType()==Attribute::FLOAT_ATTRIBUTE) { + adj->callback(statFloats, this); + } + adj->value(m_attribute->getFloat(v)); + adj->box(FL_FLAT_BOX); + adj->color(FL_BACKGROUND_COLOR, FL_SELECTION_COLOR); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + adj->deactivate(); + } + add(adj); + m_valueInputs.push_back(adj); + } + }break; + case Attribute::INT_ATTRIBUTE : + case Attribute::ACTION_INT_ATTRIBUTE : { + int inpWidth=50; + int pos=fl_width(m_name.c_str())+margin*2; + if(m_attribute->getType()==Attribute::ACTION_INT_ATTRIBUTE) { + label(""); + m_button = new Fl_Button(x+margin*2, y+margin, + pos, h-2*margin, + m_name.c_str()); + pos+=margin*4; + m_button->callback(statAction, this); + m_button->box(FL_FLAT_BOX); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + m_button->deactivate(); + } + add(m_button); + } + for(unsigned int v=0; v<m_nbValues; ++v) { + Fl_Value_Input* adj = new Fl_Value_Input( + x+pos+(inpWidth+margin)*v, + y+margin, inpWidth, h-2*margin, + ""); + adj->step(1); + adj->bounds(-10000, 10000); + if(m_attribute->getType()==Attribute::INT_ATTRIBUTE) { + adj->callback(statInts, this); + } + adj->value(m_attribute->getInt(v)); + adj->box(FL_FLAT_BOX); + adj->color(FL_BACKGROUND_COLOR, FL_SELECTION_COLOR); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + adj->deactivate(); + } + add(adj); + m_valueInputs.push_back(adj); + } + }break; + case Attribute::BOOL_ATTRIBUTE : { + int pos=fl_width(m_name.c_str())+10; + for(unsigned int v=0; v<m_nbValues; ++v) { + vector<string>& labels = m_attribute->editValueLabels(); + string lab=" X "; + if(labels.size()>v) { + lab=labels[v].c_str(); + } + Fl_Toggle_Button* adj = new Fl_Toggle_Button( + pos,y+margin, + fl_width(lab.c_str()), + h-2*margin, + lab.c_str()); + adj->copy_label(lab.c_str()); + pos+=fl_width(lab.c_str())+margin; + adj->callback(statChecks, this); + adj->value(m_attribute->getBool(v)); + adj->box(FL_FLAT_BOX); + adj->down_box(FL_DOWN_BOX); + adj->clear_visible_focus(); + adj->color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + adj->deactivate(); + } + add(adj); + m_checks.push_back(adj); + } + }break; + case Attribute::STRING_ATTRIBUTE: + case Attribute::ACTION_STRING_ATTRIBUTE: { + int inpWidth=50; + int pos=fl_width(m_name.c_str())+margin*2; + if(m_attribute->getType()==Attribute::ACTION_STRING_ATTRIBUTE) { + label(""); + m_button = new Fl_Button(x+margin*2, y+margin, + pos, h-2*margin, + m_name.c_str()); + pos+=margin*4; + m_button->callback(statAction, this); + m_button->box(FL_FLAT_BOX); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + m_button->deactivate(); + } + add(m_button); + } + + for(unsigned int v=0; v<m_nbValues; ++v) { + Fl_Widget* adj; + if(m_attribute->getStringValuesChoices().size()>v) { + Fl_Choice* ch = new Fl_Choice(x+pos+(inpWidth+margin)*v, + y+margin, inpWidth, h-2*margin, + ""); + vector<string>& choices + = m_attribute->editStringValuesChoices()[v]; + vector<string>::iterator itChoice = choices.begin(); + int c=0; + for(; itChoice!=choices.end(); ++itChoice, ++c) { + if(m_attribute->getType()==Attribute::STRING_ATTRIBUTE){ + ch->add("", 0, statChoices, this); + ch->replace(c, (*itChoice).c_str()); + } + else { + ch->add("", 0, NULL, this); + ch->replace(c, (*itChoice).c_str()); + } + if(fl_width((*itChoice).c_str())+30>inpWidth) { + inpWidth=fl_width((*itChoice).c_str())+30; + } + if(m_attribute->getString(v).compare((*itChoice))==0 ) { + ch->value(c); + } + } + ch->size(min(inpWidth,w/2),ch->h()); + m_choices.push_back(ch); + adj=ch; + } + else { + Fl_Input* inp = new Fl_Input(x+pos+(inpWidth+margin)*v, + y+margin, inpWidth, h-2*margin, + ""); + inp->value(m_attribute->getString(v).c_str()); + if(fl_width(inp->value())>inpWidth) { + inp->size(fl_width(inp->value()), inp->h()); + } + if(m_attribute->getType()==Attribute::STRING_ATTRIBUTE) { + inp->callback(statStrings, this); + } + m_inputs.push_back(inp); + adj=inp; + } + adj->when(FL_WHEN_CHANGED); + adj->box(FL_FLAT_BOX); + adj->color(FL_BACKGROUND_COLOR, FL_SELECTION_COLOR); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + adj->deactivate(); + } + add(adj); + } + }break; + case Attribute::FILE_OPEN_ATTRIBUTE : + case Attribute::FILE_SAVE_ATTRIBUTE : + case Attribute::FOLDER_OPEN_ATTRIBUTE : + case Attribute::FOLDER_SAVE_ATTRIBUTE : { + label(""); + m_button = new Fl_Button(x+margin, y+margin, + fl_width(m_name.c_str())+10, h-2*margin, + m_name.c_str()); + if(m_attribute->getType()==Attribute::FILE_OPEN_ATTRIBUTE) { + m_button->callback(statFileOpen, this); + } + else if(m_attribute->getType()==Attribute::FOLDER_OPEN_ATTRIBUTE) { + m_button->callback(statFolderOpen, this); + } + else if(m_attribute->getType()==Attribute::FOLDER_SAVE_ATTRIBUTE) { + m_button->callback(statFolderSave, this); + } + else { + m_button->callback(statFileSave, this); + } + m_button->box(FL_FLAT_BOX); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + m_button->deactivate(); + } + add(m_button); + m_output = new Fl_Output(x+m_button->w()+margin*2, + y+margin, + 60, h-2*margin, ""); + m_output->value(fl_filename_name(m_attribute->getFile().c_str())); + m_output->deactivate(); + m_output->size(fl_width(m_output->value())+10,m_output->h()); + m_output->box(FL_NO_BOX); + add(m_output); + }break; + case Attribute::ACTION_ATTRIBUTE : { + label(""); + m_button = new Fl_Button(x+margin, y+margin, + fl_width(m_name.c_str())+10, + h-2*margin, + m_name.c_str()); + m_button->callback(statAction, this); + m_button->box(FL_FLAT_BOX); + if(m_attribute->getAccessibility()==Attribute::OUTPUT) { + m_button->deactivate(); + } + add(m_button); + }break; + default:break; + } + } + + //add listeners button + m_listenersBut = new Fl_Toggle_Button(x+w-(40+margin), y+margin, + 20, h-2*margin,"L"); + m_listenersBut->callback(statShowListeners, this); + m_listenersBut->box(FL_FLAT_BOX); + m_listenersBut->color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); + add(m_listenersBut); + + //register us as guilistener of the attribute + if(m_nbValues<=4) { + m_guiListener = new GuiListener(this); + m_attribute->addListener(m_guiListener); + } + else { + m_guiListener=NULL; + } +} + +AttributeWidget::~AttributeWidget() { + if(m_guiListener) { + m_attribute->removeListener(m_guiListener); + delete m_guiListener; + } +} + +void AttributeWidget::cbFolderSave(Fl_Widget*) { + Fl_Native_File_Chooser fnfc; + fnfc.title(m_name.c_str()); + fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY); + if(fnfc.show()==0) { + m_attribute->setFile(string(fnfc.filename()), m_guiListener->getID()); + m_output->value(fl_filename_name(m_attribute->getFile().c_str())); + m_output->size(fl_width(m_output->value())+10, m_output->h()); + } +} + +void AttributeWidget::cbFolderOpen(Fl_Widget*) { + Fl_Native_File_Chooser fnfc; + fnfc.title(m_name.c_str()); + fnfc.type(Fl_Native_File_Chooser::BROWSE_DIRECTORY); + if(fnfc.show()==0) { + m_attribute->setFile(string(fnfc.filename()), m_guiListener->getID()); + m_output->value(fl_filename_name(m_attribute->getFile().c_str())); + m_output->size(fl_width(m_output->value())+10, m_output->h()); + } +} + +void AttributeWidget::cbFileOpen(Fl_Widget*) { + Fl_Native_File_Chooser fnfc; + fnfc.title(m_name.c_str()); + fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE); + if(fnfc.show()==0) { + m_attribute->setFile(string(fnfc.filename()), m_guiListener->getID()); + m_output->value(fl_filename_name(m_attribute->getFile().c_str())); + m_output->size(fl_width(m_output->value())+10, m_output->h()); + } +} + +void AttributeWidget::cbFileSave(Fl_Widget*) { + Fl_Native_File_Chooser fnfc; + fnfc.title(m_name.c_str()); + fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE); + if(fnfc.show()==0) { + m_attribute->setFile(string(fnfc.filename()), m_guiListener->getID()); + m_output->value(fl_filename_name(m_attribute->getFile().c_str())); + m_output->size(fl_width(m_output->value())+10, m_output->h()); + } +} + +void AttributeWidget::cbAction(Fl_Widget*) { + if(m_attribute->getType()==Attribute::ACTION_STRING_ATTRIBUTE) { + vector<string> vals; + if(m_attribute->getStringValuesChoices().size()>0) { + vector<Fl_Choice*>::iterator itCh = m_choices.begin(); + for(; itCh!=m_choices.end(); ++itCh) { + vals.push_back((*itCh)->text()); + } + } + else { + vector<Fl_Input*>::iterator itInp = m_inputs.begin(); + for(; itInp!=m_inputs.end(); ++itInp) { + vals.push_back((*itInp)->value()); + } + } + m_attribute->setStrings(vals, m_guiListener->getID()); + } + else if(m_attribute->getType()==Attribute::ACTION_FLOAT_ATTRIBUTE) { + vector<float> vals; + vector<Fl_Value_Input*>::iterator itInp = m_valueInputs.begin(); + for(; itInp!=m_valueInputs.end(); ++itInp) { + vals.push_back((*itInp)->value()); + } + m_attribute->setFloats(vals, m_guiListener->getID()); + } + else if(m_attribute->getType()==Attribute::ACTION_INT_ATTRIBUTE) { + vector<int> vals; + vector<Fl_Value_Input*>::iterator itInp = m_valueInputs.begin(); + for(; itInp!=m_valueInputs.end(); ++itInp) { + vals.push_back((*itInp)->value()); + } + m_attribute->setInts(vals, m_guiListener->getID()); + } + else { + m_attribute->setAction(); + } +} + +void AttributeWidget::cbFloats(Fl_Widget*) { + vector<float> vals; + vector<Fl_Value_Input*>::iterator itInp = m_valueInputs.begin(); + for(; itInp!=m_valueInputs.end(); ++itInp) { + vals.push_back((*itInp)->value()); + } + m_attribute->setFloats(vals, m_guiListener->getID()); +} + +void AttributeWidget::cbInts(Fl_Widget*) { + vector<int> vals; + vector<Fl_Value_Input*>::iterator itInp = m_valueInputs.begin(); + for(; itInp!=m_valueInputs.end(); ++itInp) { + vals.push_back((*itInp)->value()); + } + m_attribute->setInts(vals, m_guiListener->getID()); +} + +void AttributeWidget::cbStrings(Fl_Widget*) { + vector<string> vals; + vector<Fl_Input*>::iterator itInp = m_inputs.begin(); + for(; itInp!=m_inputs.end(); ++itInp) { + vals.push_back((*itInp)->value()); + } + m_attribute->setStrings(vals, m_guiListener->getID()); +} + +void AttributeWidget::cbChoices(Fl_Widget*) { + vector<string> vals; + vector<Fl_Choice*>::iterator itCh = m_choices.begin(); + for(; itCh!=m_choices.end(); ++itCh) { + vals.push_back((*itCh)->text()); + } + m_attribute->setStrings(vals, m_guiListener->getID()); +} + +void AttributeWidget::cbChecks(Fl_Widget*) { + vector<bool> vals; + vector<Fl_Toggle_Button*>::iterator itCh = m_checks.begin(); + for(; itCh!=m_checks.end(); ++itCh) { + vals.push_back((*itCh)->value()); + } + m_attribute->setBools(vals, m_guiListener->getID()); +} + +void AttributeWidget::cbShowListeners(Fl_Widget*) { + if(m_listenersBut->value()) { + MainWindow::getInstance()->showListeners(); + + //FIXME unselect other listenersbuttons in the other attribute widgets + + Fl_Pack* group = MainWindow::getInstance()->getListenersGroup(); + group->clear(); + //add one widget per listener of type osclistener + vector<Listener*>& listeners = m_attribute->editListeners(); + vector<Listener*>::iterator itLis = listeners.begin(); + for(; itLis!=listeners.end(); ++itLis) { + if((*itLis)->getListenerType().compare("OscListener")==0) { + group->add(new ListenerWidget(0, 0, group->w(), 30, *itLis)); + } + } + //add the add button + m_addListenerBut = new Fl_Button(0, 0, group->w(), 30, "Add"); + m_addListenerBut->box(FL_FLAT_BOX); + m_addListenerBut->callback(statAddListener, this); + group->add(m_addListenerBut); + group->redraw(); + } + else { + MainWindow::getInstance()->hideListeners(); + } + MainWindow::getInstance()->redraw(); +} + +void AttributeWidget::cbAddListener(Fl_Widget*) { + Listener* lis = Reveal::getInstance()->createListener("OscListener"); + if(lis!=NULL) { + m_attribute->addListener(lis); + cbShowListeners(this); + } +} + +void AttributeWidget::updateAttributeValues(vector<float>& floatValues, + vector<int>& intValues, + vector<bool>& boolValues, + vector<string>& stringValues) { + switch(m_attribute->getType()) { + case Attribute::FLOAT_ATTRIBUTE : { + unsigned int w=0; + for(;w<floatValues.size() && w<m_valueInputs.size(); ++w) { + m_valueInputs[w]->value(floatValues[w]); + } + }break; + case Attribute::INT_ATTRIBUTE : { + unsigned int w=0; + for(;w<intValues.size() && w<m_valueInputs.size(); ++w) { + m_valueInputs[w]->value(intValues[w]); + } + }break; + case Attribute::BOOL_ATTRIBUTE : { + unsigned int w=0; + for(;w<boolValues.size() && w<m_checks.size(); ++w) { + m_checks[w]->value(boolValues[w]); + } + }break; + case Attribute::FILE_OPEN_ATTRIBUTE: + case Attribute::FILE_SAVE_ATTRIBUTE: + case Attribute::FOLDER_SAVE_ATTRIBUTE: + case Attribute::FOLDER_OPEN_ATTRIBUTE: { + m_output->value(stringValues[0].c_str()); + m_output->size(fl_width(m_output->value())+10, m_output->h()); + }break; + case Attribute::STRING_ATTRIBUTE : { + unsigned int w=0; + for(;w<stringValues.size() && w<m_inputs.size(); ++w) { + m_inputs[w]->value(stringValues[w].c_str()); + } + w=0; + for(;w<stringValues.size() && w<m_choices.size(); ++w) { + m_choices[w]->value( + m_choices[w]->find_index( + stringValues[w].c_str())); + } + }break; + default:break; + } +} + diff --git a/src/gui/AttributeWidget.hpp b/src/gui/AttributeWidget.hpp new file mode 100644 index 0000000..8a0eaea --- /dev/null +++ b/src/gui/AttributeWidget.hpp @@ -0,0 +1,134 @@ +/*************************************************************************** + * AttributeWidget.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef AttributeWidget_h +#define AttributeWidget_h + +#include "../modules/Attribute.hpp" +#include <FL/Fl_Group.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Value_Input.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Output.H> +#include <FL/Fl_Choice.H> +#include <FL/Fl_Toggle_Button.H> +#include "GuiListener.hpp" + +class AttributeWidget : public Fl_Group { + public: + AttributeWidget(int x, int y, int w, int h, Attribute* attribute); + virtual ~AttributeWidget(); + + static void statFolderSave(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbFolderSave(w); + } + void cbFolderSave(Fl_Widget*); + + static void statFolderOpen(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbFolderOpen(w); + } + void cbFolderOpen(Fl_Widget*); + + static void statFileOpen(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbFileOpen(w); + } + void cbFileOpen(Fl_Widget*); + + static void statFileSave(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbFileSave(w); + } + void cbFileSave(Fl_Widget*); + + static void statAction(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbAction(w); + } + void cbAction(Fl_Widget*); + + static void statFloats(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbFloats(w); + } + void cbFloats(Fl_Widget*); + + static void statInts(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbInts(w); + } + void cbInts(Fl_Widget*); + + static void statStrings(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbStrings(w); + } + void cbStrings(Fl_Widget*); + static void statChoices(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbChoices(w); + } + void cbChoices(Fl_Widget*); + static void statChecks(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbChecks(w); + } + void cbChecks(Fl_Widget*); + + static void statShowListeners(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbShowListeners(w); + } + void cbShowListeners(Fl_Widget*); + + static void statAddListener(Fl_Widget* w, void* f){ + AttributeWidget *tmpf = static_cast<AttributeWidget*>(f); + tmpf->cbAddListener(w); + } + void cbAddListener(Fl_Widget*); + + void updateAttributeValues(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues); + + private: + Attribute* m_attribute; + std::string m_name; + std::string m_fullName; + unsigned int m_nbValues; + std::vector<bool> m_stringIsChoice; + Fl_Toggle_Button* m_listenersBut; + std::vector<Fl_Value_Input*> m_valueInputs; + std::vector<Fl_Input*> m_inputs; + std::vector<Fl_Choice*> m_choices; + std::vector<Fl_Toggle_Button*> m_checks; + Fl_Button* m_button; + Fl_Output* m_output; + Fl_Button* m_addListenerBut; + GuiListener* m_guiListener; +}; + +#endif + diff --git a/src/gui/GuiListener.cpp b/src/gui/GuiListener.cpp new file mode 100644 index 0000000..5178610 --- /dev/null +++ b/src/gui/GuiListener.cpp @@ -0,0 +1,45 @@ +/*************************************************************************** + * GuiListener.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "GuiListener.hpp" +#include <iostream> +#include <sstream> +#include "AttributeWidget.hpp" + +using namespace std; + +GuiListener::GuiListener(AttributeWidget* wid):Listener(), + m_attributeWidget(wid) { + m_listenerType="GuiListener"; +} + +void GuiListener::update(vector<float>& floatValues, + vector<int>& intValues, + vector<bool>& boolValues, + vector<string>& stringValues) { + + m_attributeWidget->updateAttributeValues(floatValues, + intValues, + boolValues, + stringValues); +} + diff --git a/src/gui/GuiListener.hpp b/src/gui/GuiListener.hpp new file mode 100644 index 0000000..8faa2d8 --- /dev/null +++ b/src/gui/GuiListener.hpp @@ -0,0 +1,45 @@ +/*************************************************************************** + * GuiListener.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef GuiListener_h +#define GuiListener_h + +#include "../modules/Listener.hpp" + +class AttributeWidget; + +class GuiListener: public Listener { + public: + GuiListener(AttributeWidget*); + virtual ~GuiListener(){} + + virtual void update(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues); + + protected: + AttributeWidget* m_attributeWidget; +}; + +#endif diff --git a/src/gui/ListenerWidget.cpp b/src/gui/ListenerWidget.cpp new file mode 100644 index 0000000..dd51b7e --- /dev/null +++ b/src/gui/ListenerWidget.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + * ListenerWidget.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "ListenerWidget.hpp" +#include <iostream> +#include <FL/fl_draw.H> +#include <FL/Fl.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Value_Input.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Input_Choice.H> +#include <FL/Fl_Native_File_Chooser.H> +#include <FL/filename.H> + +using namespace std; + +ListenerWidget::ListenerWidget(int x, int y, + int w, int h, + Listener* listener): + Fl_Group(x,y,w,h,""), + m_listener(listener) { + align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + color(FL_SELECTION_COLOR); + box(FL_BORDER_BOX); + end(); + + int margin=5; + int pos=x+margin; + vector<string>& lisParams = m_listener->editParameters(); + vector<vector<string> >& lisParVals = m_listener->editParametersValues(); + vector<string>::iterator itPar = lisParams.begin(); + vector<vector<string> >::iterator itVal = lisParVals.begin(); + for(; itPar!=lisParams.end(); ++itPar, ++itVal) { + if((*itVal).size()>0) { + Fl_Choice* inp = new Fl_Choice(pos, y+margin, + (w-40)/lisParams.size(), h-2*margin, + ""); + for(string &value : (*itVal)) { + inp->add(value.c_str()); + } + + pos+=inp->w()+margin; + inp->value(0); + inp->callback(statParams, this); + inp->when(FL_WHEN_CHANGED); + inp->box(FL_FLAT_BOX); + inp->color(FL_BACKGROUND_COLOR, FL_SELECTION_COLOR); + m_choices.push_back(inp); + add(inp); + } + else { + Fl_Input* inp = new Fl_Input(pos, y+margin, + (w-40)/lisParams.size(), h-2*margin, + ""); + pos+=inp->w()+margin; + inp->value((*itPar).c_str()); + inp->callback(statParams, this); + inp->when(FL_WHEN_CHANGED); + inp->box(FL_FLAT_BOX); + inp->color(FL_BACKGROUND_COLOR, FL_SELECTION_COLOR); + add(inp); + m_parameters.push_back(inp); + } + } + + m_removeBut = new Fl_Button(pos, y+margin, + 20, h-2*margin, "X"); + m_removeBut->callback(statRemove, this); + m_removeBut->box(FL_FLAT_BOX); + m_removeBut->color(FL_BACKGROUND_COLOR, FL_SELECTION_COLOR); + add(m_removeBut); +} + +void ListenerWidget::cbParams(Fl_Widget*) { + vector<string> params; + for(Fl_Input* inp : m_parameters) { + params.push_back(inp->value()); + } + for(Fl_Choice* inp : m_choices) { + params.push_back(inp->text(inp->value())); + } + m_listener->setParameters(params); +} + +void ListenerWidget::cbRemove(Fl_Widget*) { + m_listener->deleteListener(); +} + + diff --git a/src/gui/ListenerWidget.hpp b/src/gui/ListenerWidget.hpp new file mode 100644 index 0000000..519714a --- /dev/null +++ b/src/gui/ListenerWidget.hpp @@ -0,0 +1,57 @@ +/*************************************************************************** + * ListenerWidget.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef ListenerWidget_h +#define ListenerWidget_h + +#include "../modules/Listener.hpp" +#include <FL/Fl_Group.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Choice.H> +#include <FL/Fl_Value_Input.H> +#include <FL/Fl_Button.H> + +class ListenerWidget : public Fl_Group { + public: + ListenerWidget(int x, int y, int w, int h, Listener* listener); + virtual ~ListenerWidget() {} + + static void statParams(Fl_Widget* w, void* f){ + ListenerWidget *tmpf = static_cast<ListenerWidget*>(f); + tmpf->cbParams(w); + } + void cbParams(Fl_Widget*); + static void statRemove(Fl_Widget* w, void* f){ + ListenerWidget *tmpf = static_cast<ListenerWidget*>(f); + tmpf->cbRemove(w); + } + void cbRemove(Fl_Widget*); + + private: + Listener* m_listener; + std::vector<Fl_Input*> m_parameters; + std::vector<Fl_Choice*> m_choices; + Fl_Button* m_removeBut; +}; + +#endif + diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp new file mode 100755 index 0000000..b43d080 --- /dev/null +++ b/src/gui/MainWindow.cpp @@ -0,0 +1,250 @@ +/*************************************************************************** + * MainWindow.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "MainWindow.hpp" + +#include <iostream> +#include <FL/Fl.H> +#include <FL/Fl_Native_File_Chooser.H> +#include <FL/fl_draw.H> + +#include "../Reveal.hpp" + +using namespace std; + + +void MyDraw(const Fl_Label *o, int X, int Y, int W, int H, Fl_Align a) { + fl_font(o->font, o->size); + fl_color((Fl_Color)o->color); + fl_draw(o->value, X, Y, W, H, a, o->image, 0); +} + +void MyMeasure(const Fl_Label *o, int &W, int &H) { + fl_font(o->font, o->size); + fl_measure(o->value, W, H, 0); +} + +MainWindow::MainWindow(): Fl_Double_Window(600, 327, "Revil - Configuration"), + m_treeWidth(200), + m_attributesWidth(400) { + //resizable(this); + Fl::option(Fl::OPTION_FNFC_USES_GTK, false); + Fl::option(Fl::OPTION_VISIBLE_FOCUS, false); + Fl::scheme("gtk+"); + Fl::set_color(FL_BACKGROUND_COLOR, 200, 200, 200); + Fl::set_color(FL_BACKGROUND2_COLOR, 150, 150, 150); + Fl::set_color(FL_SELECTION_COLOR, 250, 250, 250); + Fl::set_labeltype(FL_NORMAL_LABEL, MyDraw, MyMeasure); + end(); +} + +void MainWindow::init() { + + this->color(FL_BLACK); + + m_scrollModules = new Fl_Scroll(0,0,m_treeWidth,h(),""); + m_modules= new Fl_Pack(0, + 0, + m_treeWidth, + h(), "Modules"); + m_modules->color(FL_SELECTION_COLOR); + m_modules->resizable(NULL); + m_scrollModules->end(); + m_scrollModules->color(FL_BLACK, FL_BLACK); + m_scrollModules->align(FL_ALIGN_LEFT); + + add(m_scrollModules); + + m_scrollAttributes = new Fl_Scroll(m_treeWidth,0,m_attributesWidth,h(),""); + m_attributes= new Fl_Pack(m_treeWidth, + 0, + m_attributesWidth, + h(), "Attributes"); + m_attributes->color(FL_SELECTION_COLOR); + m_scrollAttributes->end(); + m_scrollAttributes->color(FL_BLACK); + add(m_scrollAttributes); + + m_scrollListeners = new Fl_Scroll(m_treeWidth+m_attributesWidth, 0, + m_treeWidth*2, h(), + "Listeners"); + m_listeners= new Fl_Pack(m_treeWidth+m_attributesWidth, 0, + m_treeWidth*2, h(), + ""); + m_listeners->color(FL_SELECTION_COLOR); + m_scrollListeners->end(); + m_scrollListeners->color(FL_BLACK); + add(m_scrollListeners); + + callback(statQuit); + + redraw(); +} + +MainWindow::~MainWindow() { +} + +MainWindow* MainWindow::getInstance() { + static MainWindow instance; + return &instance; +} + +void MainWindow::cbQuit() { + int res = fl_choice("Save before quit ?", "Don't quit", + "Save first", "Quit without saving"); + switch(res) { + case 0: break; + case 1: { + cbSave(); + Reveal::getInstance()->quit(); + } + case 2: { + Reveal::getInstance()->quit(); + } + } +} + +void MainWindow::refreshModules(bool clearAttributes, bool clearListeners) { + if(clearAttributes) { + m_attributes->clear(); + } + if(clearListeners) { + m_listeners->clear(); + } + //refresh modules + m_modules->clear(); + m_moduleButtonsMap.clear(); + vector<Module*> modules; + Reveal::getInstance()->getSubTree(modules); + vector<Module*>::iterator itMod = modules.begin(); + for(; itMod!=modules.end(); ++itMod) { + ModuleWidget* newMod = new ModuleWidget(m_modules->x(), 10, + m_modules->w(), 30, + *itMod); + m_moduleButtonsMap[(*itMod)->getFullName()]=newMod; + newMod->callback(statTree, this); + m_modules->add(newMod); + } + + //select previously selected button if possible + if(m_moduleButtonsMap.find(m_selectedModulePath)!=m_moduleButtonsMap.end()){ + m_moduleButtonsMap[m_selectedModulePath]->value(1); + displayAttributes(m_moduleButtonsMap[m_selectedModulePath]); + } + + //redraw all + this->redraw(); +} + +void MainWindow::displayAttributes(ModuleWidget* mod) { + m_attributes->clear(); + m_scrollAttributes->scroll_to(0,0); + mod->fillGroupWithAttributes(m_attributes); + m_listeners->clear(); +} + +void MainWindow::cbTree(Fl_Widget* w) { + m_selectedModulePath=""; + int childID = m_modules->find(w); + for(int c=0; c<m_modules->children(); ++c) { + if(c==childID) { + ModuleWidget* selWid + = static_cast<ModuleWidget*>(m_modules->child(c)); + selWid->value(1); + m_selectedModulePath = selWid->getModule()->getFullName(); + displayAttributes(selWid); + redraw(); + } + else { + static_cast<Fl_Toggle_Button*>(m_modules->child(c))->value(0); + } + } +} + +int MainWindow::handle(int event) { + switch(event) { + case FL_SHORTCUT: + case FL_KEYDOWN : { + if(Fl::event_command()) { + switch(Fl::event_key()) { + case 'o': cbOpen(); return 1; + case 's': cbSave(); return 1; + case 'q': cbQuit(); return 1; + } + } + else if(Fl::event_key()==FL_Escape) { + cbQuit(); + return 1; + } + }break; + case FL_CLOSE: { + cbQuit(); + return 1; + }break; + default: break; + } + return Fl_Group::handle(event); +} + +void MainWindow::cbOpen() { + Fl_Native_File_Chooser fnfc; + fnfc.title("Open .rev file"); + fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE); + if(fnfc.show()==0) { + Reveal::getInstance()->open(fnfc.filename()); + } +} + +void MainWindow::cbSave() { + const string& fileStr = Reveal::getInstance() + ->getAttribute("save")->getFile(); + if(fileStr.compare("save")!=0 && fileStr.compare("")!=0) { + Reveal::getInstance()->save(fileStr); + } + else { + cbSaveAs(); + } +} + +void MainWindow::cbSaveAs() { + Fl_Native_File_Chooser fnfc; + fnfc.title("Save to .rev file"); + fnfc.type(Fl_Native_File_Chooser::BROWSE_SAVE_FILE); + if(fnfc.show()==0) { + Reveal::getInstance()->getAttribute("save")->setFile(fnfc.filename()); + } +} + +void MainWindow::showListeners() { + m_scrollListeners->show(); + m_scrollListeners->resize(m_treeWidth+m_attributesWidth,0, + m_treeWidth*2,h()); + size(m_treeWidth+m_attributesWidth+m_treeWidth*2, h()); + redraw(); +} + +void MainWindow::hideListeners() { + m_scrollListeners->hide(); + size(m_treeWidth+m_attributesWidth,h()); + redraw(); +} + diff --git a/src/gui/MainWindow.hpp b/src/gui/MainWindow.hpp new file mode 100755 index 0000000..f76f685 --- /dev/null +++ b/src/gui/MainWindow.hpp @@ -0,0 +1,90 @@ +/*************************************************************************** + * MainWindow.hpp + * Part of Rouages + * 2013 Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef MainWindow_h +#define MainWindow_h + +#include <string> +#include <map> + +#include <FL/Fl_Double_Window.H> +#include <FL/Fl_Tile.H> +#include <FL/Fl_Pack.H> +#include <FL/Fl_Scroll.H> +#include <FL/Fl_Toggle_Button.H> +#include <FL/Fl_Shared_Image.H> +#include <FL/Fl.H> +#include <FL/fl_ask.H> + +#include "ModuleWidget.hpp" + +class MainWindow: public Fl_Double_Window { + public: + static MainWindow* getInstance(); + ~MainWindow(); + void init(); + void refreshModules(bool clearAttributes=false, + bool clearListeners=false); + void displayAttributes(ModuleWidget*); + + static void statTree(Fl_Widget* w,void* f){ + MainWindow *tmpf = static_cast<MainWindow *>(f); + tmpf->cbTree(w); + } + void cbTree(Fl_Widget*); + + void cbOpen(); + void cbSave(); + void cbSaveAs(); + + static void statQuit(Fl_Widget* w,void* f){ + MainWindow *tmpf = static_cast<MainWindow *>(f); + tmpf->cbQuit(); + } + void cbQuit(); + int handle(int event); + + inline Fl_Pack* getListenersGroup(){return m_listeners;} + void showListeners(); + void hideListeners(); + + private: + MainWindow(); + + private: + int m_treeWidth; + int m_attributesWidth; + Fl_Scroll* m_scrollModules; + Fl_Pack* m_modules; + Fl_Scroll* m_scrollAttributes; + Fl_Pack* m_attributes; + Fl_Scroll* m_scrollListeners; + Fl_Pack* m_listeners; + + std::string m_fileName; + std::string m_selectedModulePath; + std::map<std::string, ModuleWidget*> m_moduleButtonsMap; +}; + +#endif + diff --git a/src/gui/ModuleWidget.cpp b/src/gui/ModuleWidget.cpp new file mode 100644 index 0000000..86ba71b --- /dev/null +++ b/src/gui/ModuleWidget.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * ModuleWidget.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "ModuleWidget.hpp" +#include "AttributeWidget.hpp" +#include <vector> + +using namespace std; + +ModuleWidget::ModuleWidget(int x, int y, + int w, int h, + Module* module): Fl_Toggle_Button(x,y,w,h,""), + m_module(module) { + m_label = ""; + for(int d=0; d<int(m_module->getDepth())-1; ++d) { + m_label+=" "; + } + if(m_module->getDepth()>0) { + m_label+="|-"; + } + m_label+=m_module->getName(); + label(m_label.c_str()); + align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + box(FL_BORDER_BOX); + color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); +} + +void ModuleWidget::fillGroupWithAttributes(Fl_Pack* group) { + vector<Attribute*>& attributes = m_module->editAttributes(); + vector<Attribute*>::iterator itAtt = attributes.begin(); + for(; itAtt!=attributes.end(); ++itAtt) { + if((*itAtt)->getAccessibility()!=Attribute::HIDDEN) { + group->add(new AttributeWidget(0, 0, group->w(), 30, *itAtt)); + } + } +} + + diff --git a/src/gui/ModuleWidget.hpp b/src/gui/ModuleWidget.hpp new file mode 100644 index 0000000..f2aaaac --- /dev/null +++ b/src/gui/ModuleWidget.hpp @@ -0,0 +1,44 @@ +/*************************************************************************** + * ModuleWidget.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef ModuleWidget_h +#define ModuleWidget_h + +#include "../modules/Module.hpp" +#include <FL/Fl_Toggle_Button.H> +#include <FL/Fl_Pack.H> + +class ModuleWidget : public Fl_Toggle_Button { + public: + ModuleWidget(int x, int y, int w, int h, Module* module); + virtual ~ModuleWidget() {} + void fillGroupWithAttributes(Fl_Pack*); + inline Module* getModule(){return m_module;} + + private: + Module* m_module; + std::string m_label; + +}; + +#endif + diff --git a/src/modules/Attribute.cpp b/src/modules/Attribute.cpp new file mode 100644 index 0000000..b6644f0 --- /dev/null +++ b/src/modules/Attribute.cpp @@ -0,0 +1,316 @@ +/*************************************************************************** + * Attribute.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "Attribute.hpp" + +#include <sstream> +#include <iostream> +#include <FL/fl_utf8.h> + +#include "../Reveal.hpp" +#include "Module.hpp" + +using namespace std; + +Attribute::~Attribute() { + vector<Listener*>::iterator itLis = m_listeners.begin(); + for(; itLis!=m_listeners.end(); ++itLis) { + Reveal::getInstance()->deleteListener((*itLis)); + } + m_listeners.clear(); + m_listenersMap.clear(); +} + +void Attribute::load(xmlNodePtr node) { + vector<float> floatVals; + vector<int> intVals; + vector<bool> boolVals; + vector<string> strVals; + xmlNodePtr valNode; + for(valNode=node->children; valNode; valNode=valNode->next){ + if(valNode->type == XML_ELEMENT_NODE) { + if(!xmlStrcmp(valNode->name, (const xmlChar *)"Float")) { + char* value = (char*)xmlGetProp(valNode,(xmlChar*)"value"); + if(value!=NULL) { + floatVals.push_back(atof(value)); + } + } + else if(!xmlStrcmp(valNode->name, (const xmlChar *)"Int")) { + char* value = (char*)xmlGetProp(valNode,(xmlChar*)"value"); + if(value!=NULL) { + intVals.push_back(atoi(value)); + } + } + else if(!xmlStrcmp(valNode->name, (const xmlChar *)"Bool")) { + char* value = (char*)xmlGetProp(valNode,(xmlChar*)"value"); + if(value!=NULL) { + boolVals.push_back(atoi(value)); + } + } + else if(!xmlStrcmp(valNode->name, (const xmlChar *)"String")) { + char* value = (char*)xmlGetProp(valNode,(xmlChar*)"value"); + if(value!=NULL) { + strVals.push_back(string(value)); + } + } //Listeners + else if((!xmlStrcmp(valNode->name, (const xmlChar *)"Listeners"))) { + xmlNodePtr lisNode; + for(lisNode=valNode->children;lisNode;lisNode=lisNode->next) { + if(lisNode->type == XML_ELEMENT_NODE) { + string typeStr((char*) lisNode->name); + Listener* lis = Reveal::getInstance() + ->createListener(typeStr); + if(lis!=NULL) { + lis->load(lisNode); + addListener(lis); + } + } + } + } + } + } + + if(floatVals.size()>0 && m_type==FLOAT_ATTRIBUTE) { + if(m_loadable) { + setFloats(floatVals); + } + else { + initFloats(floatVals); + } + } + else if(intVals.size()>0 && m_type==INT_ATTRIBUTE) { + if(m_loadable) { + setInts(intVals); + } + else { + initInts(intVals); + } + } + else if(boolVals.size()>0 && m_type==BOOL_ATTRIBUTE) { + if(m_loadable) { + setBools(boolVals); + } + else { + initBools(boolVals); + } + } + else if(strVals.size()>0 && m_type==STRING_ATTRIBUTE) { + if(m_loadable) { + setStrings(strVals); + } + else { + initStrings(strVals); + } + } + else if(strVals.size()>0 && m_type==FILE_OPEN_ATTRIBUTE) { + + if(FILE *file = fopen(strVals[0].c_str(), "r")) { + fclose(file); + } else if(strVals.size()>1) { + getAbsPathFromRev(strVals[1], strVals[0]); + } + + if(m_loadable) { + setFile(strVals[0]); + } + else { + initFile(strVals[0]); + } + } + else if(strVals.size()>0 && m_type==FOLDER_OPEN_ATTRIBUTE) { + if(FILE *file = fopen(strVals[0].c_str(), "r")) { + fclose(file); + } else if(strVals.size()>1) { + getAbsPathFromRev(strVals[1], strVals[0]); + } + + if(m_loadable) { + setFile(strVals[0]); + } + else { + initFile(strVals[0]); + } + } + else if(strVals.size()>0 && m_type==FILE_SAVE_ATTRIBUTE) { + initFile(strVals[0]); + } +} + +void Attribute::save(xmlNodePtr parentNode) { + xmlNodePtr newNode = xmlNewChild(parentNode, NULL, + BAD_CAST m_name.c_str(), NULL); + if(m_accessibility!=OUTPUT) { + vector<float>::iterator itFloat = m_floatValues.begin(); + for(; itFloat!=m_floatValues.end(); ++itFloat) { + xmlNodePtr valNode = xmlNewChild(newNode, NULL, + BAD_CAST "Float", NULL); + ostringstream oss; + oss<<(*itFloat); + xmlNewProp(valNode, BAD_CAST "value", BAD_CAST oss.str().c_str()); + } + vector<int>::iterator itInt = m_intValues.begin(); + for(; itInt!=m_intValues.end(); ++itInt) { + xmlNodePtr valNode = xmlNewChild(newNode, NULL, + BAD_CAST "Int", NULL); + ostringstream oss; + oss<<(*itInt); + xmlNewProp(valNode, BAD_CAST "value", BAD_CAST oss.str().c_str()); + } + vector<bool>::iterator itBool = m_boolValues.begin(); + for(; itBool!=m_boolValues.end(); ++itBool) { + xmlNodePtr valNode = xmlNewChild(newNode, NULL, + BAD_CAST "Bool", NULL); + ostringstream oss; + oss<<(*itBool); + xmlNewProp(valNode, BAD_CAST "value", BAD_CAST oss.str().c_str()); + } + //if file or folder, save path relative to current rev file + if(m_type==FILE_OPEN_ATTRIBUTE || m_type==FOLDER_OPEN_ATTRIBUTE) { + if(m_stringValues.size()>0) { + if(m_stringValues[0].compare("")!=0) { + std::string relPath; + getRelPathToRev(m_stringValues[0], relPath); + if(m_stringValues.size()<2) { + m_stringValues.push_back(""); + } + m_stringValues[1]=relPath; + } + } + } + vector<string>::iterator itStr = m_stringValues.begin(); + for(; itStr!=m_stringValues.end(); ++itStr) { + xmlNodePtr valNode = xmlNewChild(newNode, NULL, + BAD_CAST "String", NULL); + if(fl_utf8test((*itStr).c_str(),(*itStr).length())>0) { + xmlNewProp(valNode, BAD_CAST "value", + xmlCharStrdup((*itStr).c_str())); + } + } + } + + //save listeners + if(m_listeners.size()>0) { + xmlNodePtr lisNode = xmlNewChild(newNode,NULL,BAD_CAST"Listeners",NULL); + vector<Listener*>::iterator itLis = m_listeners.begin(); + for(; itLis!=m_listeners.end(); ++itLis) { + if((*itLis)->getListenerType().compare("GuiListener")!=0 && + (*itLis)->getListenerType().compare("PathListener")!=0) { + (*itLis)->save(lisNode); + } + } + } +} + +void Attribute::addListener(Listener* lis) { + unsigned int newLisID = 0; + while(m_listenersMap.find(newLisID)!=m_listenersMap.end()) { + newLisID++; + } + m_listenersMap[newLisID] = lis; + lis->setID(newLisID); + lis->setAttribute(this); + updateListenersVec(); +} + +void Attribute::removeListener(Listener* lis) { + m_listenersMap.erase(lis->getID()); + updateListenersVec(); +} + +void Attribute::updateListenersVec() { + m_listeners.clear(); + map<int, Listener*>::iterator itLis = m_listenersMap.begin(); + for(; itLis!=m_listenersMap.end(); ++itLis) { + m_listeners.push_back(itLis->second); + } + m_module->gotAttributeListenersUpdate(this); +} + +void Attribute::clearListeners() { + m_listeners.clear(); + m_listenersMap.clear(); +} + +void Attribute::sendValuesToListeners(const int& lisID) { + vector<Listener*>::iterator itLis = m_listeners.begin(); + for(; itLis!=m_listeners.end(); ++itLis) { + if((*itLis)->getID()!=lisID) { //do not send to origin listener + (*itLis)->update(m_floatValues, + m_intValues, + m_boolValues, + m_stringValues); + } + } +} + + + +void Attribute::getRelPathToRev(const string& abs, + string& rel) { + string revDir = Reveal::getInstance()->getCurrentFile(); + + revDir = revDir.substr(0, revDir.find_last_of("/\\")); + string absDir=abs.substr(0, abs.find_last_of("/\\")); + string name=abs.substr(abs.find_last_of("/\\")+1); + + bool equal=true; + while(equal) { + size_t pos1,pos2; + std::string subRev, subAbs; + pos1 = revDir.find_first_of('/'); + subRev = revDir.substr(0, pos1); + pos2 = absDir.find_first_of('/'); + subAbs = absDir.substr(0, pos2); + if(subAbs.compare(subRev)!=0) { //reached the different path + equal=false; + } + else if(pos2==string::npos) { + absDir=""; + equal=false; + } + else { + revDir = revDir.substr(pos1+1); + absDir = absDir.substr(pos2+1); + } + } + + //test if we need to go up (../) + size_t pos3=revDir.find_first_of('/'); + while(pos3!=string::npos) { + pos3 = revDir.find_first_of('/'); + if(pos3!=string::npos) { + revDir=revDir.substr(pos3+1); + absDir="../"+absDir; + } + } + rel=absDir+"/"+name; +} + + +void Attribute::getAbsPathFromRev(const string& rel, + string& abs) { + string revDir = Reveal::getInstance()->getCurrentFile(); + + revDir = revDir.substr(0, revDir.find_last_of("/\\")); + abs = revDir+"/"+rel; +} diff --git a/src/modules/Attribute.hpp b/src/modules/Attribute.hpp new file mode 100644 index 0000000..ab9ca17 --- /dev/null +++ b/src/modules/Attribute.hpp @@ -0,0 +1,330 @@ +/*************************************************************************** + * Attribute.hpp + * Part of Revil + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef Attribute_h +#define Attribute_h + +#include <string> +#include <vector> +#include <iostream> +#include <map> +#include <libxml/parser.h> +#include <libxml/tree.h> + +#include "Listener.hpp" + +class Module; + +class Attribute { + + public: + enum TYPE {FLOAT_ATTRIBUTE, + INT_ATTRIBUTE, + STRING_ATTRIBUTE, + BOOL_ATTRIBUTE, + FILE_OPEN_ATTRIBUTE, + FOLDER_OPEN_ATTRIBUTE, + FILE_SAVE_ATTRIBUTE, + FOLDER_SAVE_ATTRIBUTE, + ACTION_ATTRIBUTE, + ACTION_INT_ATTRIBUTE, + ACTION_FLOAT_ATTRIBUTE, + ACTION_STRING_ATTRIBUTE, + BLOB_ATTRIBUTE}; + + typedef void (ActionCallback) (Module*); + typedef void (FileCallback) (Module*, const std::string&); + typedef void (FloatCallback) (Module*, const std::vector<float>&); + typedef void (IntCallback) (Module*, const std::vector<int>&); + typedef void (StringCallback) (Module*,const std::vector<std::string>&); + typedef void (BoolCallback) (Module*,const std::vector<bool>&); + typedef void (BlobCallback) (Module*, const std::string&, void*); + + enum ACCESSIBILITY {HIDDEN, OUTPUT, LOCAL, GLOBAL}; + + public: + Attribute(const std::string& name, const TYPE& type, + ActionCallback* callback, Module* mod, + ACCESSIBILITY acc=GLOBAL, bool loadable=true): + m_name(name), + m_type(type), + m_module(mod), + m_nbValues(0), + m_loadable(loadable), + m_accessibility(acc), + m_actionCallback(callback){ + } + Attribute(const std::string& name, const TYPE& type, + FileCallback* callback, Module* mod, + ACCESSIBILITY acc=GLOBAL, bool loadable=true): + m_name(name), + m_type(type), + m_module(mod), + m_nbValues(1), + m_loadable(loadable), + m_accessibility(acc), + m_fileCallback(callback){ + m_stringValues.resize(1, ""); + } + Attribute(const std::string& name, const TYPE& type, + FloatCallback* callback, Module* mod, + const unsigned int& nbValues, + ACCESSIBILITY acc=GLOBAL, bool loadable=true): + m_name(name), + m_type(type), + m_module(mod), + m_nbValues(nbValues), + m_loadable(loadable), + m_accessibility(acc), + m_floatCallback(callback){ + m_floatValues.resize(nbValues,0); + } + Attribute(const std::string& name, const TYPE& type, + BoolCallback* callback, Module* mod, + const unsigned int& nbValues, + ACCESSIBILITY acc=GLOBAL, bool loadable=true): + m_name(name), + m_type(type), + m_module(mod), + m_nbValues(nbValues), + m_loadable(loadable), + m_accessibility(acc), + m_boolCallback(callback){ + m_boolValues.resize(nbValues,false); + } + Attribute(const std::string& name, const TYPE& type, + IntCallback* callback, Module* mod, + const unsigned int& nbValues, + ACCESSIBILITY acc=GLOBAL, bool loadable=true): + m_name(name), + m_type(type), + m_module(mod), + m_nbValues(nbValues), + m_loadable(loadable), + m_accessibility(acc), + m_intCallback(callback){ + m_intValues.resize(nbValues,0); + } + Attribute(const std::string& name, const TYPE& type, + StringCallback* callback, Module* mod, + const unsigned int& nbValues, + ACCESSIBILITY acc=GLOBAL, bool loadable=true): + m_name(name), + m_type(type), + m_module(mod), + m_nbValues(nbValues), + m_loadable(loadable), + m_accessibility(acc), + m_stringCallback(callback){ + m_stringValues.resize(nbValues,""); + } + + ~Attribute(); + + inline const std::string& getName(){return m_name;} + inline const TYPE& getType(){return m_type;} + inline void setFullName(const std::string& fn){m_fullName=fn;} + inline const std::string& getFullName(){return m_fullName;} + + void load(xmlNodePtr node); + void save(xmlNodePtr parentNode); + + inline const unsigned int& getNbValues(){return m_nbValues;} + + void setStrings(const std::vector<std::string>& strings, + const int& lisID=-1) { + m_stringValues.assign(strings.begin(), + strings.begin()+m_stringValues.size()); + m_stringCallback(m_module, m_stringValues); + sendValuesToListeners(lisID); + } + void setStringsIfChanged(const std::vector<std::string>& strings) { + if(strings!=m_stringValues) { + setStrings(strings); + } + } + void initStrings(const std::vector<std::string>& strings) { + m_stringValues.assign(strings.begin(), + strings.begin()+m_stringValues.size()); + sendValuesToListeners(-1); + } + const std::string& getString(const unsigned int& s) { + return m_stringValues[s]; + } + + void setFloats(const std::vector<float>& floats, + const int& lisID=-1) { + m_floatValues.assign(floats.begin(), + floats.begin()+m_floatValues.size()); + m_floatCallback(m_module, m_floatValues); + sendValuesToListeners(lisID); + } + void setFloatsIfChanged(const std::vector<float>& floats) { + if(floats!=m_floatValues) { + setFloats(floats); + } + } + void setFloatsIfChangedOrCount(const std::vector<float>& floats) { + m_changeCounter++; + if(m_changeCounter>m_count || floats!=m_floatValues) { + setFloats(floats); + m_changeCounter=0; + } + } + void initFloats(const std::vector<float>& floats) { + m_floatValues.assign(floats.begin(), + floats.begin()+m_floatValues.size()); + sendValuesToListeners(-1); + } + const float& getFloat(const unsigned int& f) {return m_floatValues[f];} + const std::vector<float>& getFloats(){return m_floatValues;} + + void setInts(const std::vector<int>& ints, + const int& lisID=-1) { + m_intValues.assign(ints.begin(), + ints.begin()+m_intValues.size()); + m_intCallback(m_module, m_intValues); + sendValuesToListeners(lisID); + } + void initInts(const std::vector<int>& ints) { + m_intValues.assign(ints.begin(), + ints.begin()+m_intValues.size()); + sendValuesToListeners(-1); + } + const int& getInt(const unsigned int& i) {return m_intValues[i];} + + void setBools(const std::vector<bool>& bools, + const int& lisID=-1) { + m_boolValues.assign(bools.begin(), + bools.begin()+m_boolValues.size()); + m_boolCallback(m_module, m_boolValues); + sendValuesToListeners(lisID); + } + void initBools(const std::vector<bool>& bools) { + m_boolValues.assign(bools.begin(), + bools.begin()+m_boolValues.size()); + sendValuesToListeners(-1); + } + bool getBool(const unsigned int& i) {return m_boolValues[i];} + + void setFile(const std::string& f, + const int& lisID=-1) { + m_stringValues[0]=f; + m_fileCallback(m_module, f); + sendValuesToListeners(lisID); + } + void initFile(const std::string& f) {m_stringValues[0]=f;} + const std::string& getFile() {return m_stringValues[0];} + + void setAction() { m_actionCallback(m_module);} + + inline const std::vector<std::string>& getValueLabels() { + return m_valuesLabels; + } + inline std::vector<std::string>& editValueLabels() { + return m_valuesLabels; + } + + inline void setChangeCount(const int& count) {m_count=count;} + inline const std::vector<float>& getValuesMin() {return m_valuesMin;} + inline std::vector<float>& editValuesMin() {return m_valuesMin;} + inline const std::vector<float>& getValuesMax() {return m_valuesMax;} + inline std::vector<float>& editValuesMax() {return m_valuesMax;} + + inline std::vector<std::vector<std::string> >& + editStringValuesChoices() { + return m_stringValuesChoices; + } + inline const std::vector<std::vector<std::string> >& + getStringValuesChoices() { + return m_stringValuesChoices; + } + + inline std::vector<Listener*>& editListeners(){return m_listeners;} + void clearListeners(); + void addListener(Listener*); + void removeListener(Listener* lis); + void updateListenersVec(); + void sendValuesToListeners(const int& lisID=-1); + + ACCESSIBILITY getAccessibility(){return m_accessibility;} + void setAccessibility(ACCESSIBILITY acc){m_accessibility=acc;} + void setLoadable(bool loadable){m_loadable=loadable;} + + private: + void getRelPathToRev(const std::string& abs, + std::string& rel); + void getAbsPathFromRev(const std::string& rel, + std::string& abs); + protected: + std::string m_name; + std::string m_fullName; + TYPE m_type; + Module* m_module; + unsigned int m_nbValues; + bool m_loadable; + ACCESSIBILITY m_accessibility; + std::vector<float> m_floatValues; + std::vector<int> m_intValues; + std::vector<bool> m_boolValues; + std::vector<std::string> m_stringValues; + int m_changeCounter; + int m_count; + + std::vector<std::string> m_valuesLabels; + + std::vector<std::vector<std::string> > m_stringValuesChoices; + std::vector<float> m_valuesMin; + std::vector<float> m_valuesMax; + + ActionCallback* m_actionCallback; + FileCallback* m_fileCallback; + FloatCallback* m_floatCallback; + IntCallback* m_intCallback; + BoolCallback* m_boolCallback; + StringCallback* m_stringCallback; + + std::vector<Listener*> m_listeners; + std::map<int, Listener*> m_listenersMap; +}; + +class AttributeValue { + public: + enum {ACTION, FLOAT_VALUE, INT_VALUE, STRING_VALUE} m_type; + + + + + private: + std::string m_label; + + std::vector<std::string >m_values; + + float m_floatValue; + int m_intValue; + std::string m_strValue; +}; + + +#endif + diff --git a/src/modules/ContextHandler.hpp b/src/modules/ContextHandler.hpp new file mode 100644 index 0000000..c792005 --- /dev/null +++ b/src/modules/ContextHandler.hpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * ContextHandler.hpp + * Part of Revil + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef ContextHandler_h +#define ContextHandler_h + +#include <glm/mat4x4.hpp> + +class ContextHandler { + public: + void setContextHandlerID(const int& id) {m_contextHandlerID=id;} + const int& getContextHandlerID(){return m_contextHandlerID;} + + inline glm::mat4& getProjMat(){return m_projMat;} + inline glm::mat4& getViewProjMat(){return m_viewProjMat;} + + inline const float& getWidth(){return m_width;} + inline const float& getHeight(){return m_height;} + + protected: + int m_contextHandlerID; + float m_width, m_height; + glm::mat4 m_projMat; + glm::mat4 m_viewProjMat; + glm::mat4 m_viewMat; +}; + + +#endif + diff --git a/src/modules/DepthCamModule.cpp b/src/modules/DepthCamModule.cpp new file mode 100644 index 0000000..ec9eb29 --- /dev/null +++ b/src/modules/DepthCamModule.cpp @@ -0,0 +1,1805 @@ +/*************************************************************************** + * DepthCamModule.cpp + * Part of Reveal + * 2015- Florent Berthaut, Alan Menit + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +/* Filtering is done using the 1€ filter by Gery Casiez et al. : + * http://cristal.univ-lille.fr/~casiez/1euro */ + + +#include "DepthCamModule.hpp" + +#include "../Reveal.hpp" +#include "SpaceModule.hpp" + +#include "ProjectorModule.hpp" + +#include "../geoms/CamGeometry.hpp" + +#include <glm/gtx/matrix_decompose.hpp> +#include <glm/gtx/matrix_operation.hpp> +#include <glm/gtx/quaternion.hpp> +#include <glm/gtx/polar_coordinates.hpp> +#include <glm/gtx/rotate_vector.hpp> +#include <glm/gtx/euler_angles.hpp> + +#include <iostream> +#include <sstream> + +using namespace std; +using namespace cv; + + +void* processFramesThreadFunction(void* pvParam) { + DepthCamModule *pThis=(DepthCamModule*)pvParam; + pThis->processFrames(); + return NULL; +} + +DepthCamModule::DepthCamModule(): GroupModule(), + DepthModule(), + m_deviceID(""), + m_open(false), + m_defaultWidth(1280), + m_defaultHeight(720), + m_defaultFps(60), + m_horizontalFOV(1), + m_verticalFOV(1), + m_mirrored(false), + m_notVoronoi(false) +{ + + m_type="DepthCam"; + m_name="depthcam"; + + m_calibrating=false; + m_depthType=0; + m_width=m_defaultWidth; + m_height=m_defaultHeight; + m_fps=m_defaultFps; + m_contourThreshold=30; + m_procSize.width=m_width; + m_procSize.height=m_height; + + m_defaultDepthFrame = new unsigned short[m_defaultWidth*m_defaultHeight]; + for(int i=0;i<m_defaultWidth*m_defaultHeight; ++i) { + m_defaultDepthFrame[i]=1000; + } + + //geometry + m_camGeom = new CamGeometry(640, 480); + m_camGeom->registerModule(this); + + //frames processing + m_framesThread=NULL; + + //filtered frame + m_filterSpat=3; + m_maxFilterSize=51; + m_filterIndex=0; + m_prevDepthFrames = new unsigned short*[m_maxFilterSize]; + for(int i=0; i<m_maxFilterSize; ++i) { + m_prevDepthFrames[i] + = new unsigned short[m_defaultWidth*m_defaultHeight]; + for(int j=0; j<m_defaultWidth*m_defaultHeight; ++j) { + m_prevDepthFrames[i][j] = 0; + } + } + m_filtDepthFrame = new unsigned short[m_defaultWidth*m_defaultHeight]; + m_sumDepthFrame = new int[m_defaultWidth*m_defaultHeight]; + for(int i=0;i<m_defaultWidth*m_defaultHeight; ++i) { + m_filtDepthFrame[i]=0; + m_sumDepthFrame[i]=0; + } + + //one euro filter + m_oefXFrame = new float[m_defaultWidth*m_defaultHeight]; + m_oefDXFrame = new float[m_defaultWidth*m_defaultHeight]; + m_oefRate=60; + m_oefDCutoff=1; + m_oefMinCutoff=1; //decrease to remove jitter + m_oefBeta=0.1; //increase to remove lag + m_oefInit=false; + + + //initialize marker detection + Size imageSize(1280, 720); + m_detRgbImg = Mat::zeros(imageSize, CV_8UC3); + m_detMarkImg = Mat::zeros(imageSize, CV_8UC3); + m_detectingMarkers=false; + m_markerPosY=0; + m_markerRotX=0; + m_markerRotY=0; + m_maxNbMarkers=10; + m_fillingMarkers=false; + m_arucoTracker = new ArucoTracker(); + m_imageTracker = new ImageTracker(); + m_currentTracker = m_arucoTracker; + m_debuggingMarkers=false; + /* + namedWindow("rgbcam"); + namedWindow("filtercam"); + */ + + //background capture + m_capturedBackground=false; + m_capturingBackground=0; + m_backgroundActive=false; + + //attributes + addAttribute(new Attribute("name", + Attribute::STRING_ATTRIBUTE, + nameCallback, this, 1, Attribute::LOCAL)); + m_attributesMap["name"]->setStrings(vector<string>(1, m_name)); + addAttribute(new Attribute("remove", + Attribute::ACTION_ATTRIBUTE, + removeCallback, this, + Attribute::LOCAL)); + addVisibleAttribute(); + addAttribute(new Attribute("refresh_devices", + Attribute::ACTION_ATTRIBUTE, + refreshCallback, this, + Attribute::LOCAL)); + addAttribute(new Attribute("open_device", + Attribute::STRING_ATTRIBUTE, + deviceCallback, this, 1, + Attribute::LOCAL)); + refreshDeviceList(); + + addAttribute(new Attribute("close_device", + Attribute::ACTION_ATTRIBUTE, + closeCallback, this, + Attribute::LOCAL)); + + addAttribute(new Attribute("mode", + Attribute::STRING_ATTRIBUTE, + modeCallback, this, 1, + Attribute::LOCAL)); + vector<string> devStr(1, ""); + m_attributesMap["mode"]->editStringValuesChoices().assign(1,devStr); + m_attributesMap["mode"]->initStrings(devStr); + + addAttribute(new Attribute("filter", + Attribute::STRING_ATTRIBUTE, + filterCallback, this, 1, + Attribute::LOCAL)); + + m_filters.push_back("none"); + m_filters.push_back("lowpass"); + m_filters.push_back("one_euro"); + m_filters.push_back("one_euro_spatial"); + m_attributesMap["filter"] + ->editStringValuesChoices().assign(1, m_filters); + m_attributesMap["filter"] + ->initStrings(vector<string>(1, m_filters[2])); + m_filter=m_filters[2]; + m_filtering=true; + + addAttribute(new Attribute("lowpass_smooth", + Attribute::FLOAT_ATTRIBUTE, + filterSizeCallback, this, 1, + Attribute::LOCAL)); + m_attributesMap["lowpass_smooth"]->initFloats(vector<float>(1,10)); + + addAttribute(new Attribute("one_euro_jitter", + Attribute::FLOAT_ATTRIBUTE, + filterMCOCallback, this, 1, + Attribute::LOCAL)); + m_attributesMap["one_euro_jitter"]->initFloats(vector<float>(1, + m_oefMinCutoff)); + addAttribute(new Attribute("one_euro_reactivity", + Attribute::FLOAT_ATTRIBUTE, + filterBetaCallback, this, 1, + Attribute::LOCAL)); + m_attributesMap["one_euro_reactivity"]->initFloats(vector<float>(1, + m_oefBeta)); + addAttribute(new Attribute("spatial_size", + Attribute::INT_ATTRIBUTE, + filterSpatCallback, this, 1, + Attribute::LOCAL)); + m_attributesMap["spatial_size"]->initInts(vector<int>(1, m_filterSpat)); + + addAttribute(new Attribute("contour_threshold", + Attribute::FLOAT_ATTRIBUTE, + contourThresholdCallback, this, 1, + Attribute::LOCAL)); + m_attributesMap["contour_threshold"]->initFloats(vector<float>(1, + m_contourThreshold)); + + addAttribute(new Attribute("calibrate_with_marker", + Attribute::ACTION_ATTRIBUTE, + calibrationCallback, this, + Attribute::LOCAL)); + + addTransformationAttributes(); + m_attributesMap["scale"]->setAccessibility(Attribute::HIDDEN); + vector<float> posVec(3,0); + posVec[2]=-700; + m_attributesMap["position"]->setFloats(posVec); + + /* + addAttribute(new Attribute("capture_background", + Attribute::BOOL_ATTRIBUTE, + captureBackgroundCallback, this, 1, + Attribute::LOCAL)); + */ + addAttribute(new Attribute("markers_detection", + Attribute::STRING_ATTRIBUTE, + markersDetectionCallback, this, 1, + Attribute::LOCAL)); + vector<string> detection; + detection.push_back("none"); + detection.push_back("aruco"); + detection.push_back("image"); + m_attributesMap["markers_detection"] + ->editStringValuesChoices().assign(1, detection); + m_attributesMap["markers_detection"] + ->initStrings(vector<string>(1, detection[0])); + addAttribute(new Attribute("image_markers_folder", + Attribute::FOLDER_OPEN_ATTRIBUTE, + imageMarkersFolderCallback, this)); + + addAttribute(new Attribute("marker_fill_method", + Attribute::STRING_ATTRIBUTE, + markersFillMethodCallback, this, 1, + Attribute::LOCAL)); + vector<string> methods; + methods.push_back("none"); + methods.push_back("flood"); + methods.push_back("voronoi"); + m_attributesMap["marker_fill_method"] + ->editStringValuesChoices().assign(1, methods); + m_attributesMap["marker_fill_method"] + ->initStrings(vector<string>(1, methods[0])); + addAttribute(new Attribute("marker_output", + Attribute::FLOAT_ATTRIBUTE, + outputMarkersCallback, this, 9, + Attribute::OUTPUT)); + addAttribute(new Attribute("debug_markers", + Attribute::BOOL_ATTRIBUTE, + debugMarkersCallback, this, 1, + Attribute::LOCAL)); + + Reveal::getInstance()->addUpdateObserver(this); + + + //start processing thread + m_framesThread = new std::thread(processFramesThreadFunction, this); +} + +DepthCamModule::~DepthCamModule() { + if(m_framesThread) { + m_framesThread->join(); + delete m_framesThread; + } + Reveal::getInstance()->removeUpdateObserver(this); + closeDevice(); +} + +void DepthCamModule::refreshDeviceList() { + openni::Array<openni::DeviceInfo> deviceList; + openni::OpenNI::enumerateDevices(&deviceList); + for(int d=0; d<deviceList.getSize(); ++d) { + cout<<"Found OpenNI device "<<deviceList[d].getUri()<<endl; + } + + m_serialsVec.clear(); + m_serialsMap.clear(); + char serialNumber[1024]; + for(int d=0; d<deviceList.getSize(); ++d) { + //ad-hoc code for libfreenect2 + if(string(deviceList[d].getUri()).find("freenect")!=string::npos) { + string serialStr = string(deviceList[d].getUri()); + serialStr=serialStr.substr(string("freenect2://0?serial=").size()); + if(serialStr.find("?")==string::npos) { + m_serialsMap[serialStr] = deviceList[d].getUri(); + m_serialsVec.push_back(serialStr); + } + } + else { + ostringstream oss; + oss<<d; + openni::Device dev; + dev.open(deviceList[d].getUri()); + dev.getProperty(ONI_DEVICE_PROPERTY_SERIAL_NUMBER, &serialNumber); + m_serialsMap[string(serialNumber)] = deviceList[d].getUri(); + m_serialsVec.push_back(string(serialNumber)); + dev.close(); + } + } + m_attributesMap["open_device"] + ->editStringValuesChoices().assign(1, m_serialsVec); +} + +void DepthCamModule::updateModelMatrix() { + GroupModule::updateModelMatrix(); + map<int, ProjectorModule*>::iterator itProj=m_attachedProjs.begin(); + for(; itProj!=m_attachedProjs.end(); ++itProj) { + itProj->second->setModelMat(m_modelMat); + } +} + +void DepthCamModule::deleteModule() { + if(m_space) { + m_space->removeCam(this); + } + Reveal::getInstance()->unregisterOutputDepthCam(this); + Module::deleteModule(); +} + +void DepthCamModule::draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& component) { + + + if(m_camTexMap.find(contextID)==m_camTexMap.end()) { + GLuint texID; + glGenTextures(1, &texID); + m_camTexMap[contextID]=texID; + m_upCamCounter[contextID]=0; + glGenTextures(1, &texID); + m_filtTexMap[contextID]=texID; + m_filtTexUpMap[contextID]=false; + glGenTextures(1, &texID); + m_markTexMap[contextID]=texID; + m_markTexUpMap[contextID]=false; + if(m_open) { + m_camTexUpMap[contextID]=false; + } + else { + m_camTexUpMap[contextID]=true; + } + } + + + /* + //captured background + if(m_backgroundActive) { + glActiveTexture(GL_TEXTURE1); + glUniform1i(uniforms[Reveal::CAMTEX2], 1); + glBindTexture(GL_TEXTURE_2D, m_camTexMap2[contextID]); + if(m_capturedBackground) { + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, + m_width, m_height, 0, + GL_RGB, GL_UNSIGNED_BYTE, + m_backImg.data); + m_capturedBackground=false; + } + } + */ + + if(m_filtering) { + glActiveTexture(GL_TEXTURE1); + glUniform1i(uniforms[Reveal::CAMTEXFIL], 1); + glBindTexture(GL_TEXTURE_2D, m_filtTexMap[contextID]); + if(m_framesLock.try_lock()) { + if(m_filtTexUpMap[contextID]) { + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + if(m_open) { + if(m_filtDepthFrame!=NULL) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, + m_width, m_height, 0, + GL_RED, GL_UNSIGNED_SHORT, + m_filtDepthFrame); + } + } + m_filtTexUpMap[contextID]=false; + } + m_framesLock.unlock(); + } + } + glActiveTexture(GL_TEXTURE0); + glUniform1i(uniforms[Reveal::CAMTEX], 0); + glBindTexture(GL_TEXTURE_2D, m_camTexMap[contextID]); + if(m_camTexUpMap[contextID]) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if(m_open) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, + m_width, m_height, 0, + GL_RED, GL_UNSIGNED_SHORT, + (unsigned char*)m_depthFrame.getData()); + } + m_camTexUpMap[contextID]=false; + } + glActiveTexture(GL_TEXTURE2); + glUniform1i(uniforms[Reveal::MARKTEX], 2); + glBindTexture(GL_TEXTURE_2D, m_markTexMap[contextID]); + if(m_detectingMarkers) { + if(m_framesLock.try_lock()) { + if(m_markTexUpMap[contextID]) { + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + if(m_open) { + if(m_markersFrame!=NULL) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, + m_width, m_height, 0, + GL_RGB, GL_UNSIGNED_BYTE, + m_markersFrame); + } + } + m_markTexUpMap[contextID]=false; + } + + vector<float> mark; + vector<s_markerAndTime>::iterator it=m_sentDetectedMarkers.begin(); + for(; it != m_sentDetectedMarkers.end(); it++) { + mark.push_back(m_depthID+it->id); + mark.push_back(1); + /* + float depth = m_rgbDepthImg.at<cv::Vec3w> + (it->y, + it->x)[2]; + glm::vec4 pos((it->x/m_width-0.5) + *depth*tan(m_horizontalFOV/2.0)*2.0, + (0.5-it->y/m_height) + *depth*tan(m_verticalFOV/2.0)*2.0, + depth, 1.0); + pos = m_modelMat * pos; + pos[0]*=-1; + mark.push_back(pos[0]); + mark.push_back(pos[1]); + mark.push_back(pos[2]); + */ + + glm::vec3 pos(0, 0, 0); + for(int c=0; c<4; c++) { + float depth = m_rgbDepthImg.at<cv::Vec3w> + (it->corners[c].y, + it->corners[c].x)[2]; + glm::vec4 cpos((it->corners[c].x/m_width-0.5) + *depth*tan(m_horizontalFOV/2.0)*2.0, + (0.5-it->corners[c].y/m_height) + *depth*tan(m_verticalFOV/2.0)*2.0, + depth, 1.0); + cpos = m_modelMat * cpos; + cpos[0]*=-1; + for(int i=0; i<3; ++i) { + it->corners3D[c][i]=cpos[i]; + pos[i]+=cpos[i]/4.0; + } + } + + //compute position + mark.push_back(pos[0]); + mark.push_back(pos[1]); + mark.push_back(pos[2]); + + //compute rotation + glm::vec3 markUp = glm::normalize(it->corners3D[1] + - it->corners3D[2]); + glm::vec3 markR = glm::normalize(it->corners3D[1] + - it->corners3D[0]); + glm::vec3 markN = glm::normalize(glm::cross(markR, markUp)); + glm::mat4x4 markM( //r,up,n + markR[0], markR[1], markR[2], 0.0, //inverser + markUp[0], markUp[1], markUp[2],0.0, + markN[0], markN[1], markN[2], 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + float rx, ry, rz; + glm::extractEulerAngleXYZ(markM, rx, ry, rz); + float tmprx = rx; + rx=-rz; + rz=-tmprx; + markM = glm::eulerAngleXYZ(rx,ry,rz); + + glm::quat markQ = glm::toQuat(markM); + /* + cout<<"Up:"<<markUp.x<<" "<<markUp.y<<" "<<markUp.z<<endl; + cout<<"R:"<<markR.x<<" "<<markR.y<<" "<<markR.z<<endl; + cout<<"N:"<<markN.x<<" "<<markN.y<<" "<<markN.z<<endl; + cout<<markQ[0]<<" "<<markQ[1]<<" "<<markQ[2]<<" "<<markQ[2]<<endl; + */ + mark.push_back(markQ[0]); + mark.push_back(markQ[1]); + mark.push_back(markQ[2]); + mark.push_back(markQ[3]); + m_attributesMap["marker_output"]->setFloats(mark); + mark.clear(); + } + m_sentDetectedMarkers.clear(); + it=m_sentRemovedMarkers.begin(); + for(; it!= m_sentRemovedMarkers.end(); it++) { + mark.push_back(m_depthID+it->id); + mark.push_back(0); + mark.push_back(0); + mark.push_back(0); + mark.push_back(0); + mark.push_back(0); + mark.push_back(0); + mark.push_back(0); + mark.push_back(0); + m_attributesMap["marker_output"]->setFloats(mark); + mark.clear(); + } + m_sentRemovedMarkers.clear(); + m_framesLock.unlock(); + } + } + glUniform1i(uniforms[Reveal::CAMFILTER], m_filtering); + glUniform1f(uniforms[Reveal::CAMCONTOURTHRESH], m_contourThreshold); + glUniform1f(uniforms[Reveal::CAMXRESO], m_width); + glUniform1f(uniforms[Reveal::CAMYRESO], m_height); + glUniform1f(uniforms[Reveal::CAMXZFACTOR], tan(m_horizontalFOV/2.0)*2.0); + glUniform1f(uniforms[Reveal::CAMYZFACTOR], tan(m_verticalFOV/2.0)*2.0); + glUniform1f(uniforms[Reveal::CAMMARKERS], m_fillingMarkers); + glUniform1i(uniforms[Reveal::BACKGROUND], m_backgroundActive); + DepthModule::draw(contextID, prog, uniforms, component); +} + +void DepthCamModule::setSpace(SpaceModule* spa) { + DepthModule::setSpace(spa); + m_space->registerGeom(m_camGeom); +} + +void DepthCamModule::setMode(const std::string& mode) { + m_defaultWidth=m_depthModes[mode].width; + m_defaultHeight=m_depthModes[mode].height; + m_defaultFps=m_depthModes[mode].fps; + if(m_open) { + openDevice(m_deviceID); + } +} + +void DepthCamModule::openDevice(const std::string& devStr, bool calib) { + if(devStr.size()==0) { + return; + } + + if(m_open) { + closeDevice(); + } + + openni::Status rc; + + if(m_serialsMap.find(devStr)==m_serialsMap.end()) { + cout<<"Could not open OpenNI device "<<devStr<<endl; + return; + } + + rc = m_device.open(m_serialsMap[devStr].c_str()); + if(rc != openni::STATUS_OK) { + cout<<"Could not open OpenNI device "<<devStr<<endl; + return; + } + + openni::VideoMode depthVideoMode; + + //create streams + rc = m_depth.create(m_device, openni::SENSOR_DEPTH); + if(rc!=openni::STATUS_OK) { + cout<<"Could not create depth stream for device "<<devStr<<endl; + return; + } + + //list and store video modes for this device + m_depthModes.clear(); + m_modes.clear(); + const openni::Array<openni::VideoMode>& modes = m_depth.getSensorInfo() + .getSupportedVideoModes(); + for(int m=0; m<modes.getSize(); ++m) { + if(modes[m].getPixelFormat()==openni::PIXEL_FORMAT_DEPTH_1_MM) { + string name = to_string(modes[m].getResolutionX()) + +"x"+to_string(modes[m].getResolutionY()) + +"@"+to_string(modes[m].getFps()); + m_modes.push_back(name); + m_depthModes[name]=DepthMode(); + m_depthModes[name].width=modes[m].getResolutionX(); + m_depthModes[name].height=modes[m].getResolutionY(); + m_depthModes[name].fps=modes[m].getFps(); + } + } + + if(m_deviceID.compare("")==0) { //no already opened device + //open a default mode + int defaultMode = 0; + m_defaultWidth=m_depthModes[m_modes[defaultMode]].width; + m_defaultHeight=m_depthModes[m_modes[defaultMode]].height; + m_defaultFps=m_depthModes[m_modes[defaultMode]].fps; + m_attributesMap["mode"]->editStringValuesChoices().assign(1,m_modes); + m_attributesMap["mode"]->initStrings(vector<string>(1, + m_modes[defaultMode])); + Reveal::getInstance()->refreshModules(); + } + + if(calib) { //fixed reso if calibrating FIXME pick the first / highest one ? + m_width=640; + m_height=480; + m_fps=30; + } + else { + m_width=m_defaultWidth; + m_height=m_defaultHeight; + m_fps=m_defaultFps; + } + + //set depth stream size + depthVideoMode.setResolution(m_width, m_height); + depthVideoMode.setFps(m_fps); + depthVideoMode.setPixelFormat(openni::PIXEL_FORMAT_DEPTH_1_MM); + openni::Status rc1 = m_depth.setVideoMode(depthVideoMode); + if(rc1!=openni::STATUS_OK) { + cout<<"Could not set depth video mode"<<endl; + return; + } + + //refresh geom size + m_camGeom->setSize(m_width, m_height); + + //color stream + rc = m_color.create(m_device, openni::SENSOR_COLOR); + openni::VideoMode colorVideoMode; + if(rc==openni::STATUS_OK) { + colorVideoMode.setResolution(m_width, m_height); + colorVideoMode.setFps(m_fps); + colorVideoMode.setPixelFormat(openni::PIXEL_FORMAT_RGB888); + rc = m_color.setVideoMode(colorVideoMode); + if(rc!=openni::STATUS_OK) { + cout<<"Could not set color video mode"<<endl; + } + } + else { + m_color.stop(); + cout<<"Could not create color stream"<<endl; + /* + rc = m_color.create(m_device, openni::SENSOR_IR); + if(rc==openni::STATUS_OK) { + colorVideoMode.setResolution(m_width, m_height); + colorVideoMode.setFps(m_fps); + colorVideoMode.setPixelFormat(openni::PIXEL_FORMAT_RGB888); + rc = m_color.setVideoMode(colorVideoMode); + if(rc!=openni::STATUS_OK) { + cout<<"Could not set ir video mode"<<endl; + } + } + else { + cout<<"Could not create ir stream"<<endl; + return; + } + */ + } + + //start only depth for now + rc = m_depth.start(); + if(!m_depth.isValid()) { + cout<<"Depth Cam: No valid streams"<<endl; + return; + } + + m_horizontalFOV = m_depth.getHorizontalFieldOfView(); + m_verticalFOV = m_depth.getVerticalFieldOfView(); + cout<<m_horizontalFOV<<" "<<m_verticalFOV<<endl; + + m_depth.setMirroringEnabled(false); + m_color.setMirroringEnabled(false); + m_device.setImageRegistrationMode( + openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR); + m_streams = new openni::VideoStream*[2]; + m_streams[0] = &m_depth; + + m_gotColor=false; + m_gotDepth=false; + m_colorActivated=false; + + m_open=true; + m_deviceID=devStr; + cout<<"Opened OpenNI device "<<m_deviceID + <<" of "<<m_width<<"x"<<m_height + <<" @ "<<m_fps<<"FPS"<<endl; +} + +void DepthCamModule::closeDevice(const bool& clear) { + if(m_open) { + m_open=false; + m_depth.destroy(); + m_color.destroy(); + delete [] m_streams; + m_device.close(); + + if(clear) { + vector<string> devStr(1, ""); + m_attributesMap["open_device"]->initStrings(devStr); + m_attributesMap["mode"]->initStrings(devStr); + m_deviceID=""; + } + } +} + +void DepthCamModule::setModuleName(const std::string& val) { + Module::setModuleName(val); + if(m_space) { + m_space->refreshDepthCamList(); + } +} + +void DepthCamModule::activateColor() { + if(m_open) { + openni::Status rc = m_color.start(); + if(!m_color.isValid()) { + cout<<"Color Cam: No valid streams"<<endl; + return; + } + m_colorActivated=true; + m_color.setMirroringEnabled(false); + m_streams[1] = &m_color; + m_device.setImageRegistrationMode( + openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR); + m_device.setDepthColorSyncEnabled(false); + } +} + +void DepthCamModule::deactivateColor() { + if(m_open) { + m_color.stop(); + m_colorActivated=false; + } +} + +bool DepthCamModule::getFrames() { + bool res=false; + + openni::VideoStream *tab[1]; + if(m_open){ + tab[0] = &m_depth; + int changedIndex=-1; + openni::OpenNI::waitForAnyStream(tab,1,&changedIndex,0); + if(changedIndex == 0) { + m_depth.readFrame(&m_depthFrame); + if(m_framesLock.try_lock()) { + m_gotDepth=true; + + createMatDepth(); + m_framesLock.unlock(); + } + if(m_capturingBackground>0) { + captureBackground(); + } + } + if(m_colorActivated){ + tab[0] = &m_color; + openni::OpenNI::waitForAnyStream(tab,1,&changedIndex,0); + if(changedIndex == 0) { + m_color.readFrame(&m_colorFrame); + if(m_framesLock.try_lock()) { + m_gotColor=true; + createMatColor(); + m_framesLock.unlock(); + } + } + } + res = m_gotDepth && (m_gotColor || !m_colorActivated); + } + return res; +} + +void DepthCamModule::attachProj(ProjectorModule* proj) { + int i=0; + while(m_attachedProjs.find(i)!=m_attachedProjs.end()) { + ++i; + } + m_attachedProjs[i]=proj; + proj->setProjID(i); + updateModelMatrix(); +} + +void DepthCamModule::detachProj(ProjectorModule* proj) { + m_attachedProjs.erase(proj->getProjID()); +} + +void DepthCamModule::setCaptureBackground(const bool& cap) { + if(cap) { + m_capturingBackground=50; + m_capturedBackground=false; + m_backgroundActive=true; + cv::Size imageSize(m_width, m_height); + m_backImg = cv::Mat::zeros(imageSize, CV_16UC1); + } + else { + m_capturingBackground=0; + m_capturedBackground=false; + m_backgroundActive=false; + } +} + +void DepthCamModule::captureBackground() { + cv::Size imageSize(m_width, m_height); + for(int j=0; j<imageSize.height; ++j) { + for(int i=0; i<imageSize.width; ++i) { + ushort& dPix = m_backImg.at<ushort>(j,i); + int coord=j*imageSize.width+i; + openni::DepthPixel depthPix = + ((openni::DepthPixel*) m_depthFrame.getData())[coord]; + if(depthPix>dPix) { + dPix=depthPix; + } + } + } + m_capturingBackground--; + if(m_capturingBackground<=0) { + m_capturedBackground=true; + } +} + +void DepthCamModule::setMarkersDetection(const string& val) { + if(m_open) { + m_framesLock.lock(); + m_framesLock.unlock(); + + if(val.compare("none")!=0) { + m_detectingMarkers=true; + activateColor(); + if(val.compare("aruco")==0) { + m_currentTracker = m_arucoTracker; + } + else { + m_currentTracker = m_imageTracker; + } + m_currentTracker->init(); + } + else { + m_detectingMarkers=false; + deactivateColor(); + } + } +} + +void DepthCamModule::setImageMarkersFolder(const std::string& fol) { + m_imageTracker->setImgFolder(fol); + m_imageTracker->init(); +} + +void DepthCamModule::setMarkersFillMethod(const std::string& val) { + if(!val.compare("none")) { + m_fillingMarkers=false; + } + else { + m_fillingMarkers=true; + if(!val.compare("voronoi")) { + m_notVoronoi=false; + } + else { + m_notVoronoi=true; + } + } +} + +void DepthCamModule::update(const int& timeDiffMs) { + if(getFrames()) { + map<int, bool>::iterator itUp = m_camTexUpMap.begin(); + for(; itUp!=m_camTexUpMap.end(); ++itUp) { + itUp->second = true; + } + } +} + + +void DepthCamModule::gotAttributeListenersUpdate(Attribute* att) { + /* + int nbLis = m_attributesMap["cursor"]->editListeners().size(); + if(nbLis>0) { + // m_outCursUniform->set(float(1)); + Reveal::getInstance()->registerOutputDepthCam(this); + } + else { + // m_outCursUniform->set(float(0)); + Reveal::getInstance()->unregisterOutputDepthCam(this); + } + */ +} + +void DepthCamModule::processCursor(const std::vector<float>& pos) { + /* + //filter cursor position + unsigned int v=0; + for(unsigned int mv=0; mv<m_filterCursorValues.size(); ++mv) { + m_filterCursorSums[mv]-=m_filterCursorValues[mv].front(); + m_filterCursorValues[mv].pop_front(); + m_filterCursorValues[mv].push_back(pos[v]); + m_filterCursorSums[mv]+=m_filterCursorValues[mv].back(); + m_cursorValues[mv]=m_filterCursorSums[mv]/m_filterCursorSize; + if(v+1<pos.size()) { + ++v; + } + } + + //set attribute + m_attributesMap["cursor"]->setFloatsIfChanged(m_cursorValues); + */ +} + +void DepthCamModule::refreshProjList(const vector<ProjectorModule*> projs) { + vector<string> labels; + labels.push_back("none"); + vector<ProjectorModule*>::const_iterator itProj=projs.begin(); + for(; itProj!=projs.end(); ++itProj) { + labels.push_back((*itProj)->getName()); + } +} + + +//-----------------------Calibration------------------------------------ + +static void cbMarkerPosY(int y, void* mod) { + static_cast<DepthCamModule*>(mod)->setCalibMarkerPosY(y); +} + +void DepthCamModule::setCalibMarkerPosY(const int& y) { + m_markerPosY=y; +} + +static void cbMarkerRotX(int x, void* mod) { + static_cast<DepthCamModule*>(mod)->setCalibMarkerRotX(x); +} + +void DepthCamModule::setCalibMarkerRotX(const int& x) { + m_markerRotX=x; +} + +static void cbMarkerRotY(int y, void* mod) { + static_cast<DepthCamModule*>(mod)->setCalibMarkerRotY(y); +} + +void DepthCamModule::setCalibMarkerRotY(const int& y) { + m_markerRotY=y; +} + +static void cbCalib(int c, void* mod) { + DepthCamModule* cam = static_cast<DepthCamModule*>(mod); + cam->setCalib(c); +} + +void DepthCamModule::setCalib(const int& c) { + m_calibrating=c; + if(c==0) { + m_calibrationStopped=true; + } +} + +void DepthCamModule::calibrate() { + if(!m_open) { + return; + } + m_calibrating=0; + m_calibrationStopped=false; + + namedWindow("DepthCamRGB"); + namedWindow("Controls"); + createTrackbar("MarkerPosY", "Controls", + &m_markerPosY, 3000, cbMarkerPosY, this); + createTrackbar("MarkerRotX", "Controls", + &m_markerRotX, 360, cbMarkerRotX, this); + createTrackbar("MarkerRotY", "Controls", + &m_markerRotY, 360, cbMarkerRotY, this); + createTrackbar("Calibrate (1:Start, 0:Cancel)", "Controls", + &m_calibrating, 1, cbCalib, this); + + + Size imageSize(m_width, m_height); + Mat kinectRgbImg = Mat::zeros(imageSize, CV_8UC3); + Mat kinectDepthImg = cv::Mat::zeros(imageSize, CV_32FC1); + + activateColor(); + + while(!m_calibrationStopped ) { + for(int j=0; j<imageSize.height; ++j) { + for(int i=0; i<imageSize.width; ++i) { + kinectDepthImg.at<float>(j,i)=0; + } + } + int nbFrames=10; + int framesCnt=0; + while(framesCnt<nbFrames) { + if(getFrames()) { + //copy to opencv mat + for(int j=0; j<imageSize.height; ++j) { + for(int i=0; i<imageSize.width; ++i) { + cv::Vec3b& pix = kinectRgbImg.at<cv::Vec3b>(j,i); + float& dPix = kinectDepthImg.at<float>(j,i); + int coord=j*imageSize.width+i; + openni::RGB888Pixel colorPix = + ((openni::RGB888Pixel*)m_colorFrame.getData())[coord]; + pix[0]=colorPix.r; + pix[1]=colorPix.g; + pix[2]=colorPix.b; + + openni::DepthPixel depthPix = + ((openni::DepthPixel*)m_depthFrame.getData())[coord]; + dPix += float(depthPix)/float(nbFrames);; + } + } + framesCnt++; + } + } + + //find marker + vector<vector<cv::Point2f> > corners; + vector<int> ids; + cv::aruco::detectMarkers(kinectRgbImg, + cv::aruco::getPredefinedDictionary(cv::aruco::DICT_ARUCO_ORIGINAL), + corners, + ids); + cv::aruco::drawDetectedMarkers(kinectRgbImg, corners); + imshow("DepthCamRGB", kinectRgbImg); + waitKey(10); + + glm::vec3 cornersD[4]; + glm::vec3 center(0.0, 0.0, 0.0); + bool valid=false; + for(unsigned int m=0; m<ids.size(); ++m) { + if(ids[m]>=0) { + valid=true; + //retrieve cam space coordinates + for(int c=0; c<4; c++) { + + glm::vec2 dCoord = glm::vec2(corners[m][c].x, + corners[m][c].y); + float& dPix = kinectDepthImg.at<float>(corners[m][c].y, + corners[m][c].x); + if(dPix<500 || dPix>7000) { + valid=false; + } + openni::CoordinateConverter::convertDepthToWorld( + m_depth, + int(dCoord.x), + int(dCoord.y), + int(dPix), + &cornersD[c].x, + &cornersD[c].y, + &cornersD[c].z); + cornersD[c].z*=1.0; + center.x+=cornersD[c].x/4.0; + center.y+=cornersD[c].y/4.0; + center.z+=cornersD[c].z/4.0; + } + } + } + + if(valid && m_calibrating) { + cout<<"center at "<<center.x<<" " + <<center.y<<" " + <<center.z<<endl; + for(int c=0;c<4;++c) { + cout<<"corner "<<c<<" "<<cornersD[c].x<<" " + <<cornersD[c].y<<" "<<cornersD[c].z<<endl; + } + + //retrieve world marker rotation + double rotX = double(m_markerRotX)/180.0*M_PI; + double rotY = double(m_markerRotY)/180.0*M_PI; + glm::mat4 markRotMat = glm::eulerAngleYXZ(rotY, rotX, 0.0); + + //cam space marker center translation + glm::mat4 markMat = glm::translate(glm::mat4(1.0), center); + + //cam space marker rotation + glm::vec3 markUp = glm::normalize(cornersD[1] - cornersD[2]); + glm::vec3 markR = glm::normalize(cornersD[1] - cornersD[0]); + glm::vec3 markN = glm::normalize(glm::cross(markR, markUp)); + cout<<"Up:"<<markUp.x<<" "<<markUp.y<<" "<<markUp.z<<endl; + cout<<"R:"<<markR.x<<" "<<markR.y<<" "<<markR.z<<endl; + cout<<"N:"<<markN.x<<" "<<markN.y<<" "<<markN.z<<endl; + glm::mat4x4 markM( //r,up,n + markR[0], markR[1], markR[2], 0.0, + markUp[0], markUp[1], markUp[2],0.0, + markN[0], markN[1], markN[2], 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + float rx, ry, rz; + glm::extractEulerAngleXYZ(markM, rx, ry, rz); + glm::mat4 rotMat = glm::eulerAngleXYZ(rx,ry,rz); + + //get transform of cam in marker space + glm::mat4 camMat = inverse(markMat*rotMat); + + //apply physical marker rotation to retrieve world space transfo + camMat = inverse(markRotMat)*camMat; + + //assign model matrix and update attached projectors + m_parentMat = glm::mat4(1.0); + setModelMat(camMat); + updateModelMatrix(); + + m_calibrationStopped=true; + } + usleep(10000); + } + cout<<"Camera Calibration Done"<<endl; + + deactivateColor(); + destroyWindow("DepthCamRGB"); + destroyWindow("Controls"); + waitKey(10); +} + +//---------------------Frames process------------------------------- + +void DepthCamModule::processFrames() { + bool done=false; + while(!done){ + if(m_open) { + bool gotFrame = false; + + m_framesLock.lock(); + + //update filtered frame texture + if(m_gotDepth) { + if(m_filtering) { + filterDepthFrame(); + } + + if(m_detectingMarkers) { + if(m_gotColor && m_gotDepth){ + gotFrame = createMatDepthAndColor(); + m_gotColor = m_gotDepth = false; + } + if(gotFrame) { + detectMarkers(); + } + } + else { + m_gotDepth=false; + } + m_gotDepth=false; + } + m_framesLock.unlock(); + + } + usleep(50000); + } +} + +bool DepthCamModule::createMatDepth(){ + + if(m_width!=m_procSize.width) { + m_procSize.width=m_width; + m_procSize.height=m_height; + } + + m_depthImg = cv::Mat::zeros(m_procSize, CV_16UC1); + + for(int j=0; j<m_procSize.height; ++j) { + for(int i=0; i<m_procSize.width; ++i) { + ushort& dPix = m_depthImg.at<ushort>(j,i); + + int coord=j*m_procSize.width+i; + + openni::DepthPixel depthPix = + ((openni::DepthPixel*) m_depthFrame.getData())[coord]; + + dPix = depthPix; + } + } + + return true; +} + +bool DepthCamModule::createMatColor(){ + if(m_width!=m_procSize.width) { + m_procSize.width=m_width; + m_procSize.height=m_height; + } + + m_rgbImg = cv::Mat::zeros(m_procSize, CV_8UC3); + + for(int j=0; j<m_procSize.height; ++j) { + for(int i=0; i<m_procSize.width; ++i) { + cv::Vec3b& cPix = m_rgbImg.at<cv::Vec3b>(j,i); + + int coord=j*m_procSize.width+i; + + openni::RGB888Pixel colorPix = + ((openni::RGB888Pixel*) m_colorFrame.getData())[coord]; + + cPix[0]=colorPix.b; + cPix[1]=colorPix.g; + cPix[2]=colorPix.r; + } + } + + return true; +} + +bool DepthCamModule::createMatDepthAndColor(){ + m_resImg = cv::Mat::zeros(m_procSize, CV_8UC3); + m_rgbDepthImg = cv::Mat::zeros(m_procSize, CV_16UC3); + + for(int j=0; j<m_procSize.height; ++j) { + for(int i=0; i<m_procSize.width; ++i) { + cv::Vec3b cPix = m_rgbImg.at<cv::Vec3b>(j,i); + ushort dPix = m_depthImg.at<ushort>(j,i); + cv::Vec3b &gl_pix = m_resImg.at<cv::Vec3b>(j,i); + cv::Vec3w &color_depth_pix = m_rgbDepthImg.at<cv::Vec3w>(j,i); + + color_depth_pix[0] = cPix[0]*255; + color_depth_pix[1] = cPix[1]*255; + color_depth_pix[2] = dPix; + + gl_pix[0] = 0; + gl_pix[1] = 0; + gl_pix[2] = 0; + } + } + + m_finalCombin = cv::Mat::zeros(m_procSize, CV_8UC3); + m_rgbDepthImg.convertTo(m_finalCombin, CV_8U, 255.0 / (5000)); + + return true; +} + +//----------------------Filtering----------------------------------- + +void DepthCamModule::setFilter(const std::string& fil) { + m_filter=fil; + if(m_filter.compare("none")==0) { + m_filtering=false; + } + else { + m_filtering=true; + } +} + +void DepthCamModule::setFilterSize(int siz) { + m_framesLock.lock(); + if(siz<m_maxFilterSize && siz>=0) { + m_filterSize=siz; + for(int i=0; i<m_procSize.width*m_procSize.height; ++i) { + for(int f=0; f<m_filterSize; ++f) { + m_prevDepthFrames[f][i]=0; + } + m_sumDepthFrame[i]=0; + } + } + m_framesLock.unlock(); +} + +void DepthCamModule::setFilterSpat(int spat) { + m_framesLock.lock(); + m_filterSpat=spat; + m_framesLock.unlock(); +} + +void DepthCamModule::setFilterMCO(float mco) { + m_framesLock.lock(); + m_oefMinCutoff=mco; + m_framesLock.unlock(); +} + +void DepthCamModule::setFilterBeta(float beta) { + m_framesLock.lock(); + m_oefBeta=beta; + m_framesLock.unlock(); +} + +void DepthCamModule::filterDepthFrame() { + if(m_filter.compare("lowpass")==0) { + for(int j=0; j<m_procSize.height; ++j) { + for(int i=0; i<m_procSize.width; ++i) { + ushort dPix = m_depthImg.at<ushort>(j,i); + int coord = j*m_procSize.width+i; + m_sumDepthFrame[coord]-= + int(m_prevDepthFrames[m_filterIndex][coord]); + m_prevDepthFrames[m_filterIndex][coord]=(unsigned short)dPix; + m_sumDepthFrame[coord]+= + int(m_prevDepthFrames[m_filterIndex][coord]); + m_filtDepthFrame[coord] = float(m_sumDepthFrame[coord]) + / float(m_filterSize); + } + } + m_filterIndex=(m_filterIndex+1)%m_filterSize; + } + else { + //1€ filter + for(int j=0; j<m_procSize.height; ++j) { + for(int i=0; i<m_procSize.width; ++i) { + ushort dPix = m_depthImg.at<ushort>(j,i); + //spatial filter + if(m_filter.compare("one_euro_spatial")==0) { + float sum=0, count=0; + for(int dy=max<int>(j-m_filterSpat,0); + dy<=min<int>(j+m_filterSpat,m_procSize.height-1); + dy++) { + for(int dx=max<int>(i-m_filterSpat,0); + dx<=min<int>(i+m_filterSpat,m_procSize.width-1); + dx++) { + ushort aPix = m_depthImg.at<ushort>(dy,dx); + if(abs(aPix-dPix)<m_contourThreshold) { + sum+=aPix; + count+=1; + } + } + } + dPix = sum/count; + } + + int coord = j*m_procSize.width+i; + float dx=0; + if(m_oefInit) { + dx=(float(dPix)-m_oefXFrame[coord])*m_oefRate; + } + float dalpha = 1.0 / (1.0 + + (1.0/(2*M_PI*m_oefDCutoff)) + / (1.0/m_oefRate)); + float edx = dx*dalpha + + (1-dalpha)*(!m_oefInit?dx:m_oefDXFrame[coord]); + m_oefDXFrame[coord]=edx; + float cutoff = m_oefMinCutoff + m_oefBeta*fabs(edx); + float alpha = 1.0 / (1.0 + + (1.0/(2*M_PI*cutoff)) + / (1.0/m_oefRate)); + + m_oefXFrame[coord] = float(dPix)*alpha + + (1-alpha)*(!m_oefInit?float(dPix):m_oefXFrame[coord]); + m_filtDepthFrame[coord]=m_oefXFrame[coord]; + } + } + if(!m_oefInit) { + m_oefInit=true; + } + } + + map<int, bool>::iterator itUp = m_filtTexUpMap.begin(); + for(; itUp!=m_filtTexUpMap.end(); ++itUp) { + itUp->second=true; + } +} + + +//-----------------------Markers------------------------------------ + +void DepthCamModule::detectMarkers() { + + vector<vector<cv::Point2f> > corners; + vector<int> ids; + + m_currentTracker->track(m_rgbImg, corners, ids); + + filterMarkers(corners, ids); + + //if got any, do filling if needed + if(!m_aliveMarkers.empty() && m_fillingMarkers){ + globalFunction(m_finalCombin); + } + + m_sentDetectedMarkers = m_detectedMarkers; + m_sentRemovedMarkers = m_removedMarkers; + m_removedMarkers.clear(); + + m_markersFrame = m_resImg.data; + map<int, bool>::iterator itUp = m_markTexUpMap.begin(); + for(; itUp!=m_markTexUpMap.end(); ++itUp) { + itUp->second=true; + } + + if(m_debuggingMarkers){ + showAliveMarkers(); + } +} + + +void DepthCamModule::draw_point(cv::Mat& img, cv::Point2f fp){ + return; +} + +void DepthCamModule::filterMarkers(vector<vector<cv::Point2f> >& cor, + vector<int>& ids) { + + //go through all detected markers, for each + m_detectedMarkers.clear(); + for(unsigned int m=0; m<ids.size(); ++m) { + if(ids[m]<10) { + //create a marker_time + m_detectedMarkers.push_back(s_markerAndTime()); + m_detectedMarkers.back().id=ids[m]; + m_detectedMarkers.back().corners.assign(cor[m].begin(),cor[m].end()); + m_detectedMarkers.back().corners3D.assign(4, glm::vec3(0)); + m_detectedMarkers.back().detected=true; + cv::Point pt = calculationCenterOfMarker(m_detectedMarkers.back()); + m_detectedMarkers.back().x=pt.x; + m_detectedMarkers.back().y=pt.y; + + //add/update detection time in map + time(&m_detectedMarkers.back().detection); + m_aliveMarkers[ids[m]] = m_detectedMarkers.back(); + } + } + + + //go through map elements, remove not detected and old ones + time_t now; + time(&now); + map<int, s_markerAndTime>::iterator itAl = m_aliveMarkers.begin(); + for(; itAl!=m_aliveMarkers.end();) { + if(difftime(now, itAl->second.detection) > 1) { + m_removedMarkers.push_back(itAl->second); + itAl = m_aliveMarkers.erase(itAl); + } + else { + itAl++; + } + } +} + +vector<cv::Point2f> DepthCamModule::newSetOfPoint(vector<cv::Point2f> points, + bool readyToCoop){ + vector<cv::Point2f> setOfPoint; + int cmp; + + if(!readyToCoop) + return points; + + for(int i = 0; i < (int)points.size(); i++){ + cmp = jointly(points, points[i]); + if(cmp == -1 || cmp > i){ + setOfPoint.push_back(points[i]); + } + } + + return setOfPoint; +} + +int DepthCamModule::jointly(vector<cv::Point2f> points, cv::Point2f pt){ + int cpt = 0; + + for(vector<cv::Point2f>::iterator it=points.begin(); it!=points.end();it++){ + if(it->x - pt.x > -130 && it->x - pt.x < 130 && it->x != pt.x) + return cpt; + + cpt++; + } + + return -1; +} + +void DepthCamModule::delimitation(cv::Mat& img) { + // Keep a copy around + //cv::Mat img_orig = img.clone(); + // Rectangle to be used with Subdiv2D + cv::Rect rect(0, 0, img.size().width, img.size().height); + // Create an instance of Subdiv2D + cv::Subdiv2D subdiv(rect); + // Create a vector of points. + vector<cv::Point2f> points; + + map<int, s_markerAndTime>::iterator it = m_aliveMarkers.begin(); + for(; it!=m_aliveMarkers.end(); it++){ + points.push_back(cv::Point2f(it->second.x, it->second.y)); + } + + vector<cv::Point2f> setOfPoint = newSetOfPoint(points, false); + + // Insert points into subdiv + subdiv.insert(setOfPoint); + + // Draw delaunay triangles + drawDelaunay(img, subdiv, cv::Scalar(13,240,231) ); + + // Draw points + for(vector<cv::Point2f>::iterator it = points.begin(); + it != points.end(); it++){ + draw_point(img, *it); + } + + + + + // Draw Voronoi diagram + drawVoronoi(m_resImg, subdiv); + + return; +} + +cv::Point DepthCamModule::calculationCenterOfMarker(s_markerAndTime& marker){ + return cv::Point((marker.corners[0].x + + marker.corners[1].x + + marker.corners[2].x + + marker.corners[3].x)/4.0, + (marker.corners[0].y + + marker.corners[1].y + + marker.corners[2].y + + marker.corners[3].y)/4.0); +} + +void DepthCamModule::globalFunction(cv::Mat &mat) { + cv::Size asize(mat.size().width, mat.size().height); + cv::Size maskSize(mat.size().width+2, mat.size().height+2); + int width = 0, height = 0; + + if(!m_notVoronoi){ + delimitation(mat); + } + else { + cv::Mat mask = cv::Mat::zeros(maskSize, CV_8UC1); + map<int, s_markerAndTime>::iterator it = m_aliveMarkers.begin(); + for(; it!= m_aliveMarkers.end(); it++) { + //FIXME values ??? + cv::floodFill(mat, mask, cv::Point(it->second.x,it->second.y), + cv::Scalar(0), nullptr, cv::Scalar(255,255,5), + cv::Scalar(255,255,5), + 4 | cv::FLOODFILL_MASK_ONLY + | ((m_depthID+it->second.id) << 8 )); + } + + for(int j=1; j<maskSize.height-1; ++j){ + for(int i=1; i<maskSize.width-1; ++i){ + cv::Vec3b &res_pix = m_resImg.at<cv::Vec3b>(j-1, i-1); + uchar mask_pix = mask.at<uchar>(j, i); + res_pix[0] = mask_pix; + res_pix[1] = mask_pix; + res_pix[2] = mask_pix; + } + } + } + return ; +} + +void DepthCamModule::drawVoronoi( cv::Mat& img, cv::Subdiv2D& subdiv) { + vector<vector<cv::Point2f> > facets; + vector<cv::Point2f> centers; + subdiv.getVoronoiFacetList(vector<int>(), facets, centers); + + vector<cv::Point> ifacet; + vector<vector<cv::Point> > pts(1); + + map<int, s_markerAndTime>::iterator it = m_aliveMarkers.begin(); + for(unsigned int f=0; + f<facets.size() && it!=m_aliveMarkers.end(); f++, it++) { + ifacet.resize(facets[f].size()); + for( size_t j = 0; j < facets[f].size(); j++ ) { + ifacet[j] = facets[f][j]; + } + cv::Scalar color((it->second.id+m_depthID), + (it->second.id+m_depthID), + (it->second.id+m_depthID)); + + cv::fillConvexPoly(img, ifacet, color, 8, 0); + + pts[0] = ifacet; + cv::polylines(img, pts, true, cv::Scalar(0,0,255), 1, LINE_AA, 0); + draw_point(img, centers[f]); + } +} + +void DepthCamModule::drawDelaunay(cv::Mat& img, cv::Subdiv2D& subdiv, + cv::Scalar delaunayColor ){ + + vector<cv::Vec6f> triangleList; + subdiv.getTriangleList(triangleList); + vector<cv::Point> pt(3); + + cv::Rect rect(0,0, img.size().width, img.size().height); + for(int i = 0; i < (int)triangleList.size(); i++){ + cv::Vec6f t = triangleList[i]; + pt[0] = cv::Point(cvRound(t[0]), cvRound(t[1])); + pt[1] = cv::Point(cvRound(t[2]), cvRound(t[3])); + pt[2] = cv::Point(cvRound(t[4]), cvRound(t[5])); + + // Draw rectangles completely inside the image. + if(rect.contains(pt[0]) &&rect.contains(pt[1]) &&rect.contains(pt[2])){ + cv::line(img, pt[0], pt[1], delaunayColor, 1, LINE_AA, 0); + cv::line(img, pt[1], pt[2], delaunayColor, 1, LINE_AA, 0); + cv::line(img, pt[2], pt[0], delaunayColor, 1, LINE_AA, 0); + } + } +} + +void DepthCamModule::debugMarkers(const bool& val) { + if(!val && m_debuggingMarkers) { + destroyWindow("markers"); + destroyWindow("filled_markers"); + waitKey(10); + } + m_debuggingMarkers=val; +} + +void DepthCamModule::showAliveMarkers() { + cv::Mat markImg(m_rgbImg); + map<int, s_markerAndTime>::iterator itM = m_aliveMarkers.begin(); + for(; itM!=m_aliveMarkers.end(); ++itM) { + ostringstream oss; + oss<<itM->second.id; + cv::putText(markImg, oss.str().c_str(), + cv::Point2f(itM->second.x, itM->second.y), + cv::FONT_HERSHEY_SIMPLEX, 2, cv::Scalar(255,255,255)); + for(int c=0; c<4; c++) { + cv::line(markImg, + itM->second.corners[c], itM->second.corners[(c+1)%4], + cv::Scalar(255), 2); + } + } + imshow("markers", markImg); + imshow("filled_markers", m_resImg*50); + waitKey(10); +} + +void ArucoTracker::init() { + + +} + +void ArucoTracker::track(cv::Mat& img, + std::vector<std::vector<cv::Point2f> >& corners, + std::vector<int>& ids) { + cv::aruco::detectMarkers(img, + cv::aruco::getPredefinedDictionary( + cv::aruco::DICT_ARUCO_ORIGINAL), + corners, + ids); + +} + + +ImageTracker::ImageTracker():Tracker() { + //m_detector = cv::ORB::create(); + //m_detector = cv::AKAZE::create(); + m_detector = cv::BRISK::create(); + m_matcher = cv::BFMatcher::create(NORM_HAMMING); +} + +void ImageTracker::init() { + m_descriptors.clear(); + m_keypoints.clear(); + m_cols.clear(); + m_rows.clear(); + + //read images from folder and compute descriptors for each + dirent** filesList; + int nbFiles = fl_filename_list(m_imgFolder.c_str(), + &filesList, fl_alphasort); + for(int f=0; f<nbFiles; ++f) { + if(filesList[f]->d_name[0]!='.') { + string fullName = m_imgFolder+string(filesList[f]->d_name); + cv::Mat img = cv::imread(fullName); + if(img.data) { + std::vector<KeyPoint> keypoints; + cv::Mat descriptors; + m_detector->detectAndCompute(img,Mat(),keypoints,descriptors); + m_descriptors.push_back(descriptors); + m_keypoints.push_back(keypoints); + m_cols.push_back(img.cols); + m_rows.push_back(img.rows); + + /* + drawKeypoints(img, keypoints, img); + imshow("marker", img); + waitKey(10); + */ + } + } + } +} + +void ImageTracker::track(cv::Mat& img, + std::vector<std::vector<cv::Point2f> >& corners, + std::vector<int>& ids) { + + unsigned int minMatches=10; + float matchRatio=0.8; + + //get descriptors for the captured image + std::vector<KeyPoint> keypoints; + cv::Mat descriptors; + m_detector->detectAndCompute(img, Mat(), keypoints, descriptors); + //drawKeypoints(img, keypoints, img); + + + + //try to match with each image in the set + for(unsigned int m=0; m<m_descriptors.size(); m++) { + vector<cv::DMatch> matches; + vector<cv::DMatch> matches2; + vector<vector<cv::DMatch> > nn_matches; + try { + //m_matcher->match(m_descriptors[m], descriptors, matches); + //m_matcher->match(descriptors, m_descriptors[m], matches2); + m_matcher->knnMatch(m_descriptors[m], descriptors, nn_matches, 2); + } + catch(Exception& e) { + cout<<e.what()<<endl; + } + + /* + vector<DMatch> good_matches; + for(int i=0; i<matches.size(); i++) { + if(matches2[i].trainIdx == matches[matches[2].trainIdx].queryIdx) { + good_matches.push_back(matches[i]); + } + } + */ + vector<DMatch> good_matches; + for(unsigned int i=0; i<nn_matches.size(); i++) { + if(nn_matches[i].size()>=2) { + if(nn_matches[i][0].distance + <= matchRatio*nn_matches[i][1].distance) { + good_matches.push_back(nn_matches[i][0]); + } + } + } + + + /* + double max_dist = 0; double min_dist = 100; + //for(int i=0; i<m_descriptors[m].rows; i++) { + for(int i=0; i<matches.size(); i++) { + double dist = matches[i].distance; + if(dist < min_dist) {min_dist = dist;} + if(dist > max_dist) {max_dist = dist;} + } + + vector<DMatch> good_matches; + //for(int i=0; i<m_descriptors[m].rows; i++) { + for(int i=0; i<matches.size(); i++) { + if(matches[i].distance < 3*min_dist) { + good_matches.push_back(matches[i]); + } + }*/ + if(good_matches.size()>minMatches) { + vector<Point2f> obj; + vector<Point2f> scene; + + for(unsigned int i=0; i<good_matches.size(); i++) { + obj.push_back(m_keypoints[m][good_matches[i].queryIdx].pt); + scene.push_back(keypoints[good_matches[i].trainIdx].pt); + } + + Mat H; + + try { + H = findHomography(obj, scene, RANSAC); + } + catch(Exception& e) { + cout<<e.what()<<endl; + } + + if(!H.empty()) { + vector<Point2f> objCorners(4); + objCorners[0] = Point(0, 0); + objCorners[1] = Point(m_cols[m], 0); + objCorners[2] = Point(m_cols[m], m_rows[m]); + objCorners[3] = Point(0, m_rows[m]); + + vector<Point2f> sceneCorners(4); + perspectiveTransform(objCorners, sceneCorners, H); + bool valid=true; + for(int c=0; c<4; c++) { + if(sceneCorners[c].x<0 || sceneCorners[c].y<0 + || sceneCorners[c].x>640 + || sceneCorners[c].y>480) { + valid=false; + } + } + + if(valid) { + ids.push_back(m); + corners.push_back(sceneCorners); + } + } + } + } + + } + + + diff --git a/src/modules/DepthCamModule.hpp b/src/modules/DepthCamModule.hpp new file mode 100644 index 0000000..ac9ee78 --- /dev/null +++ b/src/modules/DepthCamModule.hpp @@ -0,0 +1,406 @@ +/*************************************************************************** + * DepthCamModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef DepthCamModule_h +#define DepthCamModule_h + +#include "GroupModule.hpp" +#include "DepthModule.hpp" + +#include <vector> +#include <deque> +#include <thread> +#include <mutex> + +#include <OpenNI.h> +#include <opencv2/core/core.hpp> +#include <opencv2/highgui/highgui.hpp> +#include <opencv2/imgproc/imgproc.hpp> +#include <opencv2/calib3d/calib3d.hpp> +#include <opencv2/features2d/features2d.hpp> +#include <opencv2/aruco.hpp> +#include <FL/filename.H> + +class SpaceModule; +class ProjectorModule; +class CamGeometry; + +struct s_markerAndTime; +struct DepthMode; +struct ColorMode; + +class Tracker; +class ArucoTracker; +class ImageTracker; + +class DepthCamModule : public GroupModule, public DepthModule { + public: + DepthCamModule(); + virtual ~DepthCamModule(); + void deleteModule(); + void setModuleName(const std::string& val); + + inline virtual bool isDepthVisible(const unsigned int& id) { + return m_open && m_visible && (m_detectingMarkers||id==m_depthID); + } + + virtual void draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + std::map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& component); + + virtual void setSpace(SpaceModule*); + inline virtual int getNbSubDepthIDs(){return m_maxNbMarkers;} + + virtual void update(const int& timeDiffMs); + virtual void updateModelMatrix(); + + void refreshDeviceList(); + void activateColor(); + void deactivateColor(); + bool getFrames(); + inline openni::VideoFrameRef getDepthFrame(){return m_depthFrame;} + inline openni::VideoFrameRef getColorFrame(){return m_colorFrame;} + inline openni::VideoStream& getDepthStream(){return m_depth;} + + + static void refreshCallback(Module* mod) { + dynamic_cast<DepthCamModule*>(mod)->refreshDeviceList(); + } + static void deviceCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthCamModule*>(mod)->openDevice(vals[0]); + } + virtual void openDevice(const std::string& dev, bool calib=false); + static void closeCallback(Module* mod) { + dynamic_cast<DepthCamModule*>(mod)->closeDevice(true); + } + void closeDevice(const bool& clear=false); + static void modeCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setMode(vals[0]); + } + virtual void setMode(const std::string& mode); + + //filter callbacks + static void filterCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setFilter(vals[0]); + } + void setFilter(const std::string& fil); + static void filterSizeCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setFilterSize(vals[0]); + } + void setFilterSize(int siz); + static void filterSpatCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setFilterSpat(vals[0]); + } + void setFilterSpat(int siz); + static void filterMCOCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setFilterMCO(vals[0]); + } + void setFilterMCO(float mco); + static void filterBetaCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setFilterBeta(vals[0]); + } + void setFilterBeta(float beta); + + //contour callback + static void contourThresholdCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setContourThresh(vals[0]); + } + inline void setContourThresh(float cont) {m_contourThreshold=cont;} + + static void markersDetectionCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setMarkersDetection(vals[0]); + } + void setMarkersDetection(const std::string& val); + static void imageMarkersFolderCallback(Module* mod, + const std::string& f) { + dynamic_cast<DepthCamModule*>(mod)->setImageMarkersFolder(f); + } + virtual void setImageMarkersFolder(const std::string& f); + + static void markersFillMethodCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setMarkersFillMethod(vals[0]); + } + void setMarkersFillMethod(const std::string& val); + void detectMarkers(); + static void outputMarkersCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<DepthCamModule*>(mod)->outputMarkers(vals); + } + inline void outputMarkers(const std::vector<float>& vals){} + static void debugMarkersCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<DepthCamModule*>(mod)->debugMarkers(vals[0]); + } + void debugMarkers(const bool& val); + + static void captureBackgroundCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<DepthCamModule*>(mod)->setCaptureBackground(vals[0]); + } + void setCaptureBackground(const bool& cap); + void captureBackground(); + + static void calibrationCallback(Module* mod) { + dynamic_cast<DepthCamModule*>(mod)->calibrate(); + } + void calibrate(); + void refreshProjList(const std::vector<ProjectorModule*> projs); + + static void cursCallback(Module* mod, const std::vector<float>& vals) {} + + void setCalibMarkerPosY(const int&); + void setCalibMarkerRotX(const int&); + void setCalibMarkerRotY(const int&); + void setCalib(const int&); + inline double& getHorizontalFOV(){return m_horizontalFOV;} + inline double& getVerticalFOV(){return m_verticalFOV;} + + bool isOpen(){return m_open;} + + void processFrames(); + + void gotAttributeListenersUpdate(Attribute*); + void processCursor(const std::vector<float>& pos); + inline const std::string& getDeviceID(){return m_deviceID;} + + void attachProj(ProjectorModule*); + void detachProj(ProjectorModule*); + + private: + + //filter + void filterDepthFrame(); + + //marker + void draw_point(cv::Mat& img, cv::Point2f fp); + void filterMarkers(std::vector<std::vector<cv::Point2f> >& cor, + std::vector<int>& ids); + void showAliveMarkers(); + std::vector<cv::Point2f> newSetOfPoint(std::vector<cv::Point2f> points, + bool readyToCoop); + int jointly(std::vector<cv::Point2f> points, cv::Point2f pt); + void delimitation(cv::Mat& img); + cv::Point calculationCenterOfMarker(s_markerAndTime& marker); + void globalFunction(cv::Mat &mat); + cv::Scalar voronoiColor(cv::Mat mat, cv::Point2f pt); + void drawVoronoi(cv::Mat& img, cv::Subdiv2D& subdiv); + void drawDelaunay(cv::Mat& img, cv::Subdiv2D& subdiv, + cv::Scalar delaunay_color); + bool createMatDepth(); + bool createMatColor(); + bool createMatDepthAndColor(); + + private: + std::string m_deviceID; + bool m_open; + std::vector<std::string> m_modes; + std::map<std::string, DepthMode> m_depthModes; + + openni::Device m_device; + std::vector<std::string> m_serialsVec; + std::map<std::string, std::string> m_serialsMap; + openni::VideoStream m_depth, m_color; + openni::VideoStream** m_streams; + openni::VideoFrameRef m_depthFrame; + openni::VideoFrameRef m_colorFrame; + bool m_gotDepth, m_gotColor; + bool m_colorActivated; + + unsigned short* m_defaultDepthFrame; + + CamGeometry* m_camGeom; + + std::map<int, GLuint> m_camTexMap; + std::map<int, GLuint> m_camTexMap1; + std::map<int, GLuint> m_camTexMap2; + std::map<int, int> m_upCamCounter; + std::map<int, bool> m_camTexUpMap; + + std::map<int, GLuint> m_markTexMap; + std::map<int, bool> m_markTexUpMap; + + uint16_t m_width, m_height, m_fps; + uint16_t m_defaultWidth, m_defaultHeight, m_defaultFps; + double m_horizontalFOV, m_verticalFOV; + bool m_mirrored; + float m_contourThreshold; + + //frames processing + cv::Size m_procSize; + std::thread* m_framesThread; + std::mutex m_framesLock; + + //filter + bool m_filtering; + std::string m_filter; + int m_filterSize; + std::vector<std::string> m_filters; + int m_maxFilterSize; + int m_filterIndex; + unsigned short** m_prevDepthFrames; + int* m_sumDepthFrame; + unsigned short* m_filtDepthFrame; + std::map<int, GLuint> m_filtTexMap; + std::map<int, bool> m_filtTexUpMap; + int m_filterSpat; + + //one euro filter + float* m_oefXFrame; + float* m_oefDXFrame; + float m_oefRate; + float m_oefMinCutoff; + float m_oefBeta; + float m_oefDCutoff; + bool m_oefInit; + + //background + int m_capturingBackground; + bool m_capturedBackground; + bool m_backgroundActive; + cv::Mat m_backImg; + + //markers + bool m_detectingMarkers; + unsigned char *m_markersFrame; + cv::Mat m_detRgbImg; + cv::Mat m_detMarkImg; + cv::Mat m_detDepthImg; + int m_maxNbMarkers; + bool m_fillingMarkers; + Tracker* m_currentTracker; + ArucoTracker* m_arucoTracker; + ImageTracker* m_imageTracker; + bool m_debuggingMarkers; + + //calibration + int m_calibrating; + bool m_calibrationStopped; + int m_redXmm, m_redYmm, m_redZmm; + int m_greenXmm, m_greenYmm, m_greenZmm; + int m_blueXmm, m_blueYmm, m_blueZmm; + int m_patternWidth; + int m_patternPositionX; + int m_patternPositionY; + int m_markerPosY; + int m_markerRotX; + int m_markerRotY; + ProjectorModule* m_calibrationProj; + std::vector<cv::Point3f> m_worldCorners; + cv::Size m_patternSize; + + //projectors + std::map<int, ProjectorModule*> m_attachedProjs; + + //cursor + float m_filterCursorSize; + std::vector<float> m_filterCursorSums; + std::vector<std::deque<float> > m_filterCursorValues; + std::vector<float> m_cursorValues; + + //markerDetection + cv::Mat m_finalCombin; + cv::Mat m_rgbImg; + cv::Mat m_depthImg; + cv::Mat m_rgbDepthImg; + cv::Mat m_resImg; + std::vector<s_markerAndTime> m_detectedMarkers; + std::map<int, s_markerAndTime> m_aliveMarkers; + std::vector<s_markerAndTime> m_removedMarkers; + std::vector<s_markerAndTime> m_sentDetectedMarkers; + std::vector<s_markerAndTime> m_sentRemovedMarkers; + bool m_notVoronoi; +}; + + +//------------------------------Trackers------------------- + +class Tracker { + public : + virtual ~Tracker(){} + virtual void init()=0; + virtual void track(cv::Mat&, + std::vector<std::vector<cv::Point2f> >&, + std::vector<int>&)=0; +}; + +class ArucoTracker : public Tracker { + public: + ~ArucoTracker(){} + void init(); + void track(cv::Mat&, + std::vector<std::vector<cv::Point2f> >&, + std::vector<int>&); + +}; + +struct s_markerAndTime { + int id; + float x; + float y; + std::vector<cv::Point2f> corners; + std::vector<glm::vec3> corners3D; + int plan = -1; + time_t detection; + time_t timeLess; + glm::vec3 orientation; + bool detected; +}; + +class ImageTracker : public Tracker { + public: + ImageTracker(); + ~ImageTracker(){} + void init(); + void track(cv::Mat&, + std::vector<std::vector<cv::Point2f> >&, + std::vector<int>&); + void setImgFolder(const std::string& fol){m_imgFolder=fol;} + private: + std::string m_imgFolder; + std::vector<cv::Mat> m_descriptors; + std::vector<std::vector<cv::KeyPoint> > m_keypoints; + cv::Ptr<cv::Feature2D> m_detector; + std::vector<int> m_rows; + std::vector<int> m_cols; + cv::Ptr<cv::DescriptorMatcher> m_matcher; +}; + +struct DepthMode { + int width; + int height; + int fps; +}; + +#endif + diff --git a/src/modules/DepthGroupModule.cpp b/src/modules/DepthGroupModule.cpp new file mode 100644 index 0000000..50fb245 --- /dev/null +++ b/src/modules/DepthGroupModule.cpp @@ -0,0 +1,116 @@ +/*************************************************************************** + * DepthGroupModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "DepthGroupModule.hpp" + +#include <iostream> + +#include "../Reveal.hpp" + +#include "ProjectorModule.hpp" +#include "DepthCamModule.hpp" +#include "DepthMeshModule.hpp" +#include "DepthShapeModule.hpp" +#include "SpaceModule.hpp" + +using namespace std; + +DepthGroupModule::DepthGroupModule(): GroupModule(), DepthModule() { + m_type="DepthGroup"; + m_name="group"; + + addAttribute(new Attribute("name", + Attribute::STRING_ATTRIBUTE, + nameCallback, this, 1, Attribute::LOCAL)); + m_attributesMap["name"]->setStrings(vector<string>(1, m_name)); + + addRemoveAttribute(); + addVisibleAttribute(); + addAttribute(new Attribute("add_projector", + Attribute::ACTION_ATTRIBUTE, + addProjCallback, this, Attribute::LOCAL)); + addAttribute(new Attribute("add_depth_group", + Attribute::ACTION_STRING_ATTRIBUTE, + addDepthGroupCallback, this, 1, + Attribute::LOCAL)); + m_attributesMap["add_depth_group"]->initStrings(vector<string>(1,"group")); + addAttribute(new Attribute("add_depth_camera", + Attribute::ACTION_ATTRIBUTE, + addCamCallback, this, Attribute::LOCAL)); + addAttribute(new Attribute("add_depth_shape", + Attribute::ACTION_STRING_ATTRIBUTE, + addDepthShapeCallback, this, 1)); + m_attributesMap["add_depth_shape"]->initStrings(vector<string>(1,"shape")); + addAttribute(new Attribute("add_depth_mesh", + Attribute::ACTION_STRING_ATTRIBUTE, + addDepthMeshCallback, this, 1)); + m_attributesMap["add_depth_mesh"]->initStrings(vector<string>(1,"mesh")); + + addTransformationAttributes(); +} + +DepthGroupModule::~DepthGroupModule() { +} + +void DepthGroupModule::deleteModule() { + Module::deleteModule(); +} + +void DepthGroupModule::updateModelMatrix() { + GroupModule::updateModelMatrix(); +} + +void DepthGroupModule::addChild(Module* mod) { + GroupModule::addChild(mod); + m_space->addSpaceModule(mod); + Reveal::getInstance()->refreshModules(); +} + +void DepthGroupModule::addProj() { + ProjectorModule* proj = new ProjectorModule(); + addChild(proj); +} + +void DepthGroupModule::addCam() { + DepthCamModule* cam = new DepthCamModule(); + addChild(cam); +} + +void DepthGroupModule::addDepthShape(const string& name) { + DepthShapeModule* tmp = new DepthShapeModule(); + tmp->setName(name); + addChild(tmp); +} + +void DepthGroupModule::addDepthMesh(const string& name) { + DepthMeshModule* tmp = new DepthMeshModule(); + tmp->setName(name); + addChild(tmp); +} + +void DepthGroupModule::addDepthGroup(const string& name) { + DepthGroupModule* tmp = new DepthGroupModule(); + tmp->setName(name); + addChild(tmp); +} + diff --git a/src/modules/DepthGroupModule.hpp b/src/modules/DepthGroupModule.hpp new file mode 100644 index 0000000..e99a0b6 --- /dev/null +++ b/src/modules/DepthGroupModule.hpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * DepthGroupModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef DepthGroupModule_h +#define DepthGroupModule_h + +#include "GroupModule.hpp" +#include "DepthModule.hpp" + +class DepthCamModule; +class DepthMeshModule; +class ProjectorModule; +class DepthShapeModule; + +class DepthGroupModule : public GroupModule, public DepthModule { + public: + DepthGroupModule(); + virtual ~DepthGroupModule(); + void deleteModule(); + + virtual void addChild(Module*); + + virtual void updateModelMatrix(); + + static void nameCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthGroupModule*>(mod)->setName(vals[0]); + } + + static void addProjCallback(Module* mod) { + dynamic_cast<DepthGroupModule*>(mod)->addProj(); + } + void addProj(); + + static void addCamCallback(Module* mod) { + dynamic_cast<DepthGroupModule*>(mod)->addCam(); + } + void addCam(); + + static void addDepthShapeCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthGroupModule*>(mod)->addDepthShape(vals[0]); + } + void addDepthShape(const std::string& name); + + static void addDepthMeshCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthGroupModule*>(mod)->addDepthMesh(vals[0]); + } + void addDepthMesh(const std::string& name); + + static void addDepthGroupCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<DepthGroupModule*>(mod)->addDepthGroup(vals[0]); + } + void addDepthGroup(const std::string& name); + + private: +}; + + +#endif + diff --git a/src/modules/DepthMeshModule.cpp b/src/modules/DepthMeshModule.cpp new file mode 100644 index 0000000..76ad0c6 --- /dev/null +++ b/src/modules/DepthMeshModule.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * DepthMeshModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "DepthMeshModule.hpp" + +#include <iostream> + +#include "../Reveal.hpp" +#include "SpaceModule.hpp" +#include "../geoms/Geometry.hpp" + +using namespace std; + +DepthMeshModule::DepthMeshModule(): DepthModule() { + m_type="DepthMesh"; + m_name="depthmesh"; + m_depthType=1; + + m_meshGeom = new Geometry(); + m_meshGeom->registerModule(this); + m_meshGeom->editCompoSizes().push_back(0); + + + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + + addAttribute(new Attribute("add_vertex", + Attribute::ACTION_FLOAT_ATTRIBUTE, + addVertexCallback, this, 3)); + addAttribute(new Attribute("clear_vertices", + Attribute::ACTION_ATTRIBUTE, + clearVerticesCallback, this)); + + addTransformationAttributes(); +} + +DepthMeshModule::~DepthMeshModule() { +} + +void DepthMeshModule::updateModelMatrix() { + DepthModule::updateModelMatrix(); +} + +void DepthMeshModule::setSpace(SpaceModule* space) { + DepthModule::setSpace(space); + m_space->registerGeom(m_meshGeom); + +} + +void DepthMeshModule::addVertex(const float& x, + const float& y, + const float& z) { + vector<GLfloat>& vertices = m_meshGeom->editVertexBufferData(); + vector<GLuint>& indices = m_meshGeom->editIndexBufferData(); + vector<int>& sizes = m_meshGeom->editCompoSizes(); + + vertices.push_back(x); + vertices.push_back(y); + vertices.push_back(z); + indices.push_back(indices.size()); + sizes[0]+=1; + m_meshGeom->refresh(); +} + +void DepthMeshModule::clearVertices() { + vector<GLfloat>& vertices = m_meshGeom->editVertexBufferData(); + vector<GLuint>& indices = m_meshGeom->editIndexBufferData(); + vector<int>& sizes = m_meshGeom->editCompoSizes(); + indices.clear(); + vertices.clear(); + sizes[0]=0; + +} + + + diff --git a/src/modules/DepthMeshModule.hpp b/src/modules/DepthMeshModule.hpp new file mode 100644 index 0000000..b29e614 --- /dev/null +++ b/src/modules/DepthMeshModule.hpp @@ -0,0 +1,55 @@ +/*************************************************************************** + * DepthMeshModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef DepthMeshModule_h +#define DepthMeshModule_h + +#include "DepthModule.hpp" + +class DepthMeshModule : public DepthModule { + public: + DepthMeshModule(); + virtual ~DepthMeshModule(); + virtual void updateModelMatrix(); + virtual void setSpace(SpaceModule* space); + + static void addVertexCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<DepthMeshModule*>(mod)->addVertex(vals[0], + vals[1], + vals[2]); + } + void addVertex(const float& z, const float& y, const float& x); + + static void clearVerticesCallback(Module* mod) { + dynamic_cast<DepthMeshModule*>(mod)->clearVertices(); + } + void clearVertices(); + + private: + Geometry* m_meshGeom; +}; + + +#endif + diff --git a/src/modules/DepthModule.cpp b/src/modules/DepthModule.cpp new file mode 100644 index 0000000..486a47a --- /dev/null +++ b/src/modules/DepthModule.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * DepthModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "DepthModule.hpp" + +#include <iostream> + +#include "../Reveal.hpp" +#include "SpaceModule.hpp" + +using namespace std; + +DepthModule::DepthModule(): GeomModule(), m_space(NULL) {} + +DepthModule::~DepthModule() {} + +void DepthModule::deleteModule() { + if(m_space) { + m_space->removeDepthModule(this); + } + Module::deleteModule(); +} + +void DepthModule::setDepthID(const unsigned int& id) { + m_depthID=id; +} + +void DepthModule::setSpace(SpaceModule* space) { + m_space=space; +} + +void DepthModule::draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& component) { + + GeomModule::draw(contextID, prog, uniforms, component); + glUniform1i(uniforms[Reveal::DEPTHTYPE], m_depthType); + glUniform1i(uniforms[Reveal::DEPTHID], m_depthID); +} + + + diff --git a/src/modules/DepthModule.hpp b/src/modules/DepthModule.hpp new file mode 100644 index 0000000..b292f0e --- /dev/null +++ b/src/modules/DepthModule.hpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * DepthModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef DepthModule_h +#define DepthModule_h + +#include "ShapeModule.hpp" + +class SpaceModule; + +class DepthModule : public virtual GeomModule { + public: + DepthModule(); + virtual ~DepthModule(); + void deleteModule(); + + void setDepthID(const unsigned int&); + const unsigned int& getDepthID(){return m_depthID;} + + virtual void setSpace(SpaceModule* space); + + virtual void draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + std::map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& component); + inline virtual int getNbSubDepthIDs(){return 1;} + + inline virtual bool isDepthVisible(const unsigned int& id) { + return m_visible; + } + + protected: + unsigned int m_depthID; + int m_depthType; + SpaceModule* m_space; +}; + + +#endif + diff --git a/src/modules/DepthShapeModule.cpp b/src/modules/DepthShapeModule.cpp new file mode 100644 index 0000000..3f9438e --- /dev/null +++ b/src/modules/DepthShapeModule.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * DepthShapeModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "DepthShapeModule.hpp" + +#include <iostream> + +#include "../Reveal.hpp" +#include "SpaceModule.hpp" +#include "../geoms/Geometry.hpp" + +using namespace std; + +DepthShapeModule::DepthShapeModule(): ShapeModule(), DepthModule() { + m_type="DepthShape"; + m_name="depthshape"; + m_depthType=1; + + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + addShapeAttributes(); + addTransformationAttributes(); + addFollowMarkerAttribute(); + + vector<float> dims(3,200.0); + dims[2]=1; + m_attributesMap["dimensions"]->setFloats(dims); +} + +DepthShapeModule::~DepthShapeModule() { + m_space->getGeom(m_shapesMap[m_currentShape]) + ->unregisterModule(this); +} + +void DepthShapeModule::updateModelMatrix() { + ShapeModule::updateModelMatrix(); +} + +void DepthShapeModule::setSpace(SpaceModule* space) { + DepthModule::setSpace(space); + m_space->getGeom(m_shapesMap[m_currentShape])->registerModule(this); +} + +void DepthShapeModule::setShape(const std::string& shape) { + bool found=false; + vector<string>::iterator itIns=m_shapes.begin(); + for(; itIns!=m_shapes.end(); ++itIns) { + if((*itIns).compare(shape)==0) { + found=true; + } + } + if(found) { + if(m_currentShape.compare("")!=0) { + m_space->getGeom(m_shapesMap[m_currentShape]) + ->unregisterModule(this); + } + m_currentShape=shape; + m_space->getGeom(m_shapesMap[m_currentShape]) + ->registerModule(this); + } +} + diff --git a/src/modules/DepthShapeModule.hpp b/src/modules/DepthShapeModule.hpp new file mode 100644 index 0000000..f45adb9 --- /dev/null +++ b/src/modules/DepthShapeModule.hpp @@ -0,0 +1,42 @@ +/*************************************************************************** + * DepthShapeModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef DepthShapeModule_h +#define DepthShapeModule_h + +#include "ShapeModule.hpp" +#include "DepthModule.hpp" + +class DepthShapeModule : public ShapeModule, public DepthModule { + public: + DepthShapeModule(); + virtual ~DepthShapeModule(); + virtual void updateModelMatrix(); + virtual void setSpace(SpaceModule* space); + void setShape(const std::string& shape); + private: +}; + + +#endif + diff --git a/src/modules/GeomModule.cpp b/src/modules/GeomModule.cpp new file mode 100644 index 0000000..3ddaf6d --- /dev/null +++ b/src/modules/GeomModule.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * GeomModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "GeomModule.hpp" +#include "../geoms/Geometry.hpp" + +using namespace std; +using namespace glm; + +GeomModule::GeomModule(): Module(), + m_localInsideAxes(true), + m_currentGeom(NULL) { + m_subShapeInvMats.push_back(glm::mat4(1)); +} + +GeomModule::~GeomModule() {} + +void GeomModule::draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& component) { + glUniformMatrix4fv(uniforms[Reveal::MODELMAT], 1, + GL_FALSE, value_ptr(m_modelMat)); + if(prog==Reveal::RENDERPROG) { + glUniformMatrix4fv(uniforms[Reveal::INVMODELMAT], 1, + GL_FALSE, value_ptr(m_invModelMat)); + glUniform3fv(uniforms[Reveal::MODELSCALE], 1, value_ptr(m_modelScale)); + + glUniformMatrix4fv(uniforms[Reveal::SUBSHAPEINVMAT], 1, + GL_FALSE, value_ptr(m_subShapeInvMats[component])); + glUniform1f(uniforms[Reveal::SUBSHAPEID], component); + glUniform1f(uniforms[Reveal::SUBSHAPESNB], m_subShapeInvMats.size()); + } +} + +void GeomModule::deleteModule() { + if(m_currentGeom) { + m_currentGeom->unregisterModule(this); + } + Module::deleteModule(); +} + + + diff --git a/src/modules/GeomModule.hpp b/src/modules/GeomModule.hpp new file mode 100644 index 0000000..0aa00bd --- /dev/null +++ b/src/modules/GeomModule.hpp @@ -0,0 +1,57 @@ +/*************************************************************************** + * GeomModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef GeomModule_h +#define GeomModule_h + +#include "Module.hpp" + +#include "../Reveal.hpp" + +class GeomModule : public virtual Module { + public: + GeomModule(); + virtual ~GeomModule(); + void deleteModule(); + + virtual void draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + std::map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& component=0); + + virtual void setGeomID(const unsigned int& id){m_geomID=id;} + virtual const unsigned int& getGeomID(){return m_geomID;} + + protected: + unsigned int m_geomID; + bool m_localInsideAxes; + Geometry* m_currentGeom; + std::vector<glm::mat4> m_subShapeInvMats; + std::map<int, glm::vec4> m_boundingRect; + std::map<int, bool> m_boundingRectUpdate; + glm::vec3 m_bbPnts[2]; +}; + + +#endif + diff --git a/src/modules/GroupModule.cpp b/src/modules/GroupModule.cpp new file mode 100644 index 0000000..805193d --- /dev/null +++ b/src/modules/GroupModule.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** + * GroupModule.cpp + * Part of GroupModule + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "GroupModule.hpp" + +#include <iostream> +#include "../Reveal.hpp" + +using namespace std; + +GroupModule::GroupModule():Module() { + m_type="Group"; +} + +GroupModule::~GroupModule() {} + +void GroupModule::draw() { + vector<Module*>::iterator itChild = m_children.begin(); + for(; itChild!=m_children.end(); ++itChild) { + (*itChild)->draw(); + } +} + +void GroupModule::deleteModule() { + deleteChildren(); + Module::deleteModule(); +} + +void GroupModule::deleteChildren() { + while(m_children.size()>0) { + m_children.back()->deleteModule(); + } + m_childrenMap.clear(); +} + +void GroupModule::addChild(Module* mod) { + unsigned int newChildID=0; + while(m_childrenMap.find(newChildID)!=m_childrenMap.end()) { + newChildID++; + } + m_childrenMap[newChildID]=mod; + m_children.push_back(mod); + mod->setChildID(newChildID); + mod->setParent(this); + mod->setDepth(m_depth+1); + updateModelMatrix(); + setVisible(m_visible); +} + +void GroupModule::removeChild(Module* mod) { + m_childrenMap.erase(mod->getChildID()); + vector<Module*>::iterator itChild = m_children.begin(); + for(; itChild!=m_children.end();) { + if((*itChild)->getChildID()==mod->getChildID()) { + itChild=m_children.erase(itChild); + } + else { + ++itChild; + } + } +} + +void GroupModule::getSubTree(std::vector<Module*>& children) { + children.push_back(this); + vector<Module*>::iterator itChild = m_children.begin(); + for(; itChild!=m_children.end(); ++itChild) { + (*itChild)->getSubTree(children); + } +} + +void GroupModule::load(xmlNodePtr node) { + Module::load(node); + xmlNodePtr modsNode; + for(modsNode=node->children; modsNode; modsNode=modsNode->next){ + if(modsNode->type == XML_ELEMENT_NODE && + !xmlStrcmp(modsNode->name, (const xmlChar *) "Modules")) { + xmlNodePtr modNode; + for(modNode=modsNode->children; modNode; modNode=modNode->next){ + if(modNode->type == XML_ELEMENT_NODE) { + string typeStr((char*) modNode->name); + Module* mod = Reveal::getInstance()->createModule(typeStr); + if(mod) { + addChild(mod); + mod->load(modNode); + } + } + } + } + } +} + +xmlNodePtr GroupModule::save(xmlNodePtr parentNode) { + xmlNodePtr newNode = Module::save(parentNode); + xmlNodePtr modsNode = xmlNewChild(newNode, NULL, + BAD_CAST "Modules", NULL); + vector<Module*>::iterator itChild = m_children.begin(); + for(; itChild!=m_children.end(); ++itChild) { + (*itChild)->save(modsNode); + } + return newNode; +} + +void GroupModule::listModulesAndAttributes(const std::string& parentName, + std::map<std::string, Module*>& mods, + std::map<std::string, Attribute*>& atts) { + Module::listModulesAndAttributes(parentName, mods, atts); + vector<Module*>::iterator itChild = m_children.begin(); + for(; itChild!=m_children.end(); ++itChild) { + (*itChild)->listModulesAndAttributes(parentName+"/"+m_name, mods, atts); + } +} + +void GroupModule::updateModelMatrix() { + Module::updateModelMatrix(); + vector<Module*>::iterator itChild = m_children.begin(); + for(; itChild!=m_children.end(); ++itChild) { + (*itChild)->setParentMatrix(m_modelMat); + (*itChild)->updateModelMatrix(); + } +} + +void GroupModule::setVisible(bool vis) { + m_visible=vis; + vector<Module*>::iterator itChild = m_children.begin(); + for(; itChild!=m_children.end(); ++itChild) { + (*itChild)->setParentVisible(m_parentVisible&&m_visible); + } +} + +void GroupModule::setParentVisible(bool pvis) { + m_parentVisible=pvis; + setVisible(m_visible); +} + +void GroupModule::getVisibleFromList(std::vector<string>& modVec, + std::map<std::string, int>& modMap) { + vector<Module*>::iterator itChild = m_children.begin(); + for(; itChild!=m_children.end(); ++itChild) { + (*itChild)->getVisibleFromList(modVec, modMap); + } +} + diff --git a/src/modules/GroupModule.hpp b/src/modules/GroupModule.hpp new file mode 100644 index 0000000..ba06922 --- /dev/null +++ b/src/modules/GroupModule.hpp @@ -0,0 +1,59 @@ +/*************************************************************************** + * GroupModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef GroupModule_h +#define GroupModule_h + +#include "Module.hpp" + +class GroupModule: public virtual Module { + public: + GroupModule(); + virtual ~GroupModule(); + virtual void draw(); + virtual void addChild(Module* mod); + virtual void removeChild(Module* mod); + virtual void getSubTree(std::vector<Module*>& children); + void deleteModule(); + void deleteChildren(); + + virtual void load(xmlNodePtr node); + virtual xmlNodePtr save(xmlNodePtr parentNode); + + void listModulesAndAttributes(const std::string& parentName, + std::map<std::string, Module*>& mods, + std::map<std::string, Attribute*>& atts); + virtual void updateModelMatrix(); + virtual void setVisible(bool vis); + virtual void setParentVisible(bool pvis); + + virtual void getVisibleFromList(std::vector<std::string>& modVec, + std::map<std::string, int>& modMap); + + protected: + std::vector<Module*> m_children; + std::map<unsigned int, Module*> m_childrenMap; +}; + +#endif + diff --git a/src/modules/Listener.cpp b/src/modules/Listener.cpp new file mode 100644 index 0000000..fa277b5 --- /dev/null +++ b/src/modules/Listener.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + * Listener.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "Listener.hpp" +#include <iostream> +#include <sstream> +#include "Attribute.hpp" +#include "../Reveal.hpp" + +using namespace std; + +Listener::Listener():m_saved(true){} + +void Listener::deleteListener() { + m_attribute->removeListener(this); + Reveal::getInstance()->deleteListener(this); +} + +void Listener::setParameters(const vector<string>& params) { + if(params.size()==m_parameters.size()) { + m_parameters=params; + } +} + +void Listener::load(xmlNodePtr lisNode) { + vector<string> params; + xmlNodePtr paramNode; + for(paramNode=lisNode->children; paramNode; paramNode=paramNode->next){ + if(paramNode->type == XML_ELEMENT_NODE) { + if(!xmlStrcmp(paramNode->name, (const xmlChar *)"Parameter")) { + char* value = (char*)xmlGetProp(paramNode,(xmlChar*)"value"); + if(value!=NULL) { + params.push_back(value); + } + } + } + } + setParameters(params); +} + +void Listener::save(xmlNodePtr parentNode) { + if(m_saved) { + xmlNodePtr lisNode = xmlNewChild(parentNode, NULL, + BAD_CAST m_listenerType.c_str(), + NULL); + vector<string>::iterator itParam = m_parameters.begin(); + for(; itParam!=m_parameters.end(); ++itParam) { + xmlNodePtr parNode = xmlNewChild(lisNode, NULL, + BAD_CAST "Parameter", NULL); + xmlNewProp(parNode,BAD_CAST"value",BAD_CAST (*itParam).c_str()); + } + } +} + diff --git a/src/modules/Listener.hpp b/src/modules/Listener.hpp new file mode 100644 index 0000000..8ed8c7b --- /dev/null +++ b/src/modules/Listener.hpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Listener.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef Listener_h +#define Listener_h + +#include <string> +#include <vector> +#include <libxml/parser.h> +#include <libxml/tree.h> + +class Attribute; + +class Listener { + public: + Listener(); + virtual ~Listener(){} + void deleteListener(); + + virtual void load(xmlNodePtr node); + virtual void save(xmlNodePtr parentNode); + + virtual void update(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues)=0; + + inline const int& getID(){return m_listenerID;} + inline void setID(const int& id){m_listenerID=id;} + inline virtual void setAttribute(Attribute* att){m_attribute=att;} + inline Attribute* getAttribute(){return m_attribute;} + + inline std::vector<std::string>& editParameters(){return m_parameters;} + inline std::vector<std::vector<std::string> >& editParametersValues() { + return m_parametersValues; + } + virtual void setParameters(const std::vector<std::string>& par); + + inline const std::string& getListenerType(){return m_listenerType;} + inline std::string& editListenerType(){return m_listenerType;} + + + protected: + int m_listenerID; + Attribute* m_attribute; + std::string m_listenerType; + std::vector<std::string> m_parameters; + std::vector<std::vector<std::string> > m_parametersValues; + bool m_saved; +}; + +#endif diff --git a/src/modules/ModelModule.cpp b/src/modules/ModelModule.cpp new file mode 100644 index 0000000..6b3f746 --- /dev/null +++ b/src/modules/ModelModule.cpp @@ -0,0 +1,286 @@ +/*************************************************************************** + * ModelModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define AI_CONFIG_PP_SBP_REMOVE aiPrimitiveType_LINE|aiPrimitiveType_POINT + +#include "ModelModule.hpp" + +#include <iostream> +#include <fstream> +#include <sstream> + +#include "../Reveal.hpp" +#include <glm/gtx/matrix_decompose.hpp> +#include <glm/gtx/quaternion.hpp> +#include <glm/gtx/polar_coordinates.hpp> +#include "opencv2/imgproc/imgproc.hpp" +#include <opencv2/highgui/highgui.hpp> + +#include <assimp/Importer.hpp> +#include <assimp/scene.h> +#include <assimp/postprocess.h> + +#include "../geoms/Geometry.hpp" + +using namespace std; +using namespace glm; + +ModelModule::ModelModule(): GeomModule() { + m_type="Model"; + m_name="model"; + + m_modelGeom = new Geometry(); + Reveal::getInstance()->registerGeom(m_modelGeom); + m_modelGeom->registerModule(this); + + m_coordImage = new float[m_texWidth*m_texHeight*2]; +} + +ModelModule::~ModelModule() {} + +void ModelModule::addModelAttributes() { + addAttribute(new Attribute("model", + Attribute::FILE_OPEN_ATTRIBUTE, + modelCallback, this)); + addAttribute(new Attribute("dimensions", + Attribute::FLOAT_ATTRIBUTE, + dimensionsCallback, this, 3)); + m_attributesMap["dimensions"]->setFloats(vector<float>(3,100.0)); +} + +void ModelModule::updateModelMatrix() { + Module::updateModelMatrix(); + + mat4 dimMat = scale(m_dimensions); + m_modelMat = m_modelMat * dimMat; + m_invModelMat = inverse(m_modelMat); + + vec3 decTrans, decSkew; + quat decRot; + vec4 decPers; + decompose(m_modelMat, m_modelScale, decRot, decTrans, decSkew, decPers); + + /* + //update bounding box as well + vec4 pnts[8]; + vec4 locpnts[8]; + int p=0; + for(float x=-0.5; x<1; x+=1.0) { + for(float y=-0.5; y<1; y+=1.0) { + for(float z=-0.5; z<1; z+=1.0) { + pnts[p] = m_modelMat*vec4(x, y, z, 1.0); + locpnts[p] = vec4(m_modelScale[0]*x, + m_modelScale[1]*y, + m_modelScale[2]*z, + 1.0); + ++p; + } + } + } + m_bbPnts[0]=pnts[0]; + m_bbPnts[1]=pnts[0]; + for(p=1; p<8; ++p) { + for(int c=0; c<3;++c) { + m_bbPnts[0][c]=std::min<float>(pnts[p][c], m_bbPnts[0][c]); + m_bbPnts[1][c]=std::max<float>(pnts[p][c], m_bbPnts[1][c]); + } + } + + for(auto &up : m_boundingRectUpdate) { + up.second=true; + } +*/ + + //update bounding box as well + /* + vec4 pnts[8]; + vec4 locpnts[8]; + int p=0; + for(int x=0; x<2; x++) { + for(int y=0; y<2; y++) { + for(int z=0; z<2; z++) { + pnts[p] = m_modelMat*vec4(m_bbPnts[x].x, m_bbPnts[y].y, + m_bbPnts[z].z, 1.0); + locpnts[p] = vec4(decScale[0]*m_bbPnts[x].x, + decScale[1]*m_bbPnts[y].y, + decScale[2]*m_bbPnts[z].z, + 1.0); + ++p; + } + } + } + m_bboxMins[0]=pnts[0]; + vec4 bboxMax=pnts[0]; + vec4 bboxLocMin=locpnts[0]; + vec4 bboxLocMax=locpnts[0]; + for(p=1; p<8; ++p) { + for(int c=0; c<3;++c) { + m_bboxMins[0][c]=std::min<float>(pnts[p][c], m_bboxMins[0][c]); + bboxMax[c]=std::max<float>(pnts[p][c], bboxMax[c]); + bboxLocMin[c]=std::min<float>(locpnts[p][c], bboxLocMin[c]); + bboxLocMax[c]=std::max<float>(locpnts[p][c], bboxLocMax[c]); + } + } + + for(unsigned int c=0; c<m_modelGeom->editCompoSizes().size(); ++c) { + //store min and size (max-min) + m_bboxMins[c]=m_bboxMins[0]; + m_bboxSizes[c] = bboxMax-m_bboxMins[c]; + m_bboxLocalMin[c] = bboxLocMin; + m_bboxLocalSizes[c] = bboxLocMax-bboxLocMin; + + if(m_localInsideAxes) { + m_bboxRots[0] = glm::inverse(toMat4(decRot)); + } + else { + m_bboxRots[c] = mat4(1.0); + } + }*/ + +} + +void ModelModule::setDimensions(const float& x, const float& y,const float& z) { + m_dimensions=vec3(x, y, z); + updateModelMatrix(); +} + +void ModelModule::setModel(const std::string& fileName) { + m_modelStr = ""; + + vector<GLfloat>& vertices = m_modelGeom->editVertexBufferData(); + vector<GLuint>& indices = m_modelGeom->editIndexBufferData(); + vector<int>& sizes = m_modelGeom->editCompoSizes(); + m_modelGeom->hasTexCoords(true); + + vertices.clear(); + indices.clear(); + sizes.clear(); + + float fMax = std::numeric_limits<float>::max(); + float fMin = -std::numeric_limits<float>::max(); + m_bbPnts[0] = glm::vec3(fMax, fMax, fMax); + m_bbPnts[1] = glm::vec3(fMin, fMin, fMin); + + memset(m_coordImage, 0, m_texWidth*m_texHeight*2*sizeof(float)); + + + string dir = fileName.substr(0, fileName.find_last_of("/"))+"/"; + + + Assimp::Importer importer; + const aiScene* scene = importer.ReadFile( fileName, + aiProcess_Triangulate | + aiProcess_JoinIdenticalVertices | + aiProcess_SortByPType); + if(!scene) { + cout<<"Error opening model "<<fileName<<endl; + return; + } + + if(scene->HasMeshes()) { + for(unsigned int ma=0;ma<scene->mNumMaterials;++ma) { + int nbTex=scene->mMaterials[ma]->GetTextureCount( + aiTextureType_DIFFUSE); + if(nbTex>0) { + aiString texName; + scene->mMaterials[ma]->GetTexture(aiTextureType_DIFFUSE, + 0, &texName); + if(m_attributesMap.find("surface_texture") + !=m_attributesMap.end()) { + string tName = texName.C_Str(); + m_attributesMap["surface_texture"]->setFile(dir+"/"+tName); + } + } + } + + //compute bbox size + aiVector3D minV = aiVector3D(fMax, fMax, fMax); + aiVector3D maxV = aiVector3D(fMin, fMin, fMin); + for(unsigned int m=0; m<scene->mNumMeshes; ++m) { + aiMesh* mesh = scene->mMeshes[m]; + for(unsigned int v=0; v<mesh->mNumVertices; ++v) { + aiVector3D& vert = mesh->mVertices[v]; + for(int i=0; i<3; i++) { + minV[i] = std::min<float>(minV[i], vert[i]); + maxV[i] = std::max<float>(maxV[i], vert[i]); + } + } + } + + vector<float> dims = {fabs(maxV[0]-minV[0]), + fabs(maxV[1]-minV[1]), + fabs(maxV[2]-minV[2])}; + vector<float> cnt = {(maxV[0]+minV[0])/2.0f, + (maxV[1]+minV[1])/2.0f, + (maxV[2]+minV[2])/2.0f}; + + unsigned int meshCnt=0; + for(unsigned int m=0; m<scene->mNumMeshes; ++m) { + aiMesh* mesh = scene->mMeshes[m]; + //write indices + for(unsigned int f=0; f<mesh->mNumFaces; ++f) { + aiFace& face = mesh->mFaces[f]; + for(unsigned int i=0; i<face.mNumIndices; ++i) { + indices.push_back(face.mIndices[i]+meshCnt); + } + } + sizes.push_back(mesh->mNumFaces*3); + meshCnt+=mesh->mNumVertices; + + //write normalized vertices and texcoords + for(unsigned int v=0; v<mesh->mNumVertices; ++v) { + aiVector3D& vert = mesh->mVertices[v]; + for(int i=0; i<3; ++i) { + vertices.push_back((vert[i]-minV[i])/(maxV[i]-minV[i])-0.5); + } + if(mesh->HasTextureCoords(0)) { + vertices.push_back(mesh->mTextureCoords[0][v][0]); + vertices.push_back(mesh->mTextureCoords[0][v][1]); + } + else { + vertices.push_back(0); + vertices.push_back(0); + } + + } + } + + //write bounding box + m_bbPnts[0].x = -0.5; + m_bbPnts[0].y = -0.5; + m_bbPnts[0].z = -0.5; + m_bbPnts[1].x = 0.5; + m_bbPnts[1].y = 0.5; + m_bbPnts[1].z = 0.5; + + //write dimensions + m_attributesMap["dimensions"]->setFloats(dims); + m_attributesMap["position"]->setFloats(cnt); + + m_modelStr = fileName; + } + + + m_modelGeom->refresh(); + updateModelMatrix(); +} + diff --git a/src/modules/ModelModule.hpp b/src/modules/ModelModule.hpp new file mode 100644 index 0000000..32b0d21 --- /dev/null +++ b/src/modules/ModelModule.hpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * ModelModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef ModelModule_h +#define ModelModule_h + +#include "GeomModule.hpp" + +class ModelModule : public virtual GeomModule { + public: + ModelModule(); + virtual ~ModelModule(); + + static void modelCallback(Module* mod, + const std::string& f) { + dynamic_cast<ModelModule*>(mod)->setModel(f); + } + virtual void setModel(const std::string&); + static void dimensionsCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<ModelModule*>(mod)->setDimensions(vals[0], + vals[1], + vals[2]); + } + void setDimensions(const float&, const float&, const float&); + + virtual void updateModelMatrix(); + void addModelAttributes(); + + protected: + Geometry* m_modelGeom; + float* m_coordImage; + glm::vec3 m_dimensions; + std::string m_modelStr; + + private: + struct ModelVertex { + glm::vec3 pos; + glm::vec2 tex; + bool compare(ModelVertex& v) { + if(v.pos.x==pos.x && v.pos.y==pos.y && v.pos.z==pos.z + && v.tex.x==tex.x && v.tex.y==tex.y) { + return true; + } + return false; + } + }; +}; + + +#endif + diff --git a/src/modules/Module.cpp b/src/modules/Module.cpp new file mode 100644 index 0000000..2c4eea1 --- /dev/null +++ b/src/modules/Module.cpp @@ -0,0 +1,423 @@ +/*************************************************************************** + * Module.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "Module.hpp" +#include <iostream> +#include <limits> +#include <sstream> + +#include <glm/gtx/euler_angles.hpp> +#include <glm/gtx/quaternion.hpp> +#include <glm/gtx/matrix_decompose.hpp> +#include <glm/gtx/norm.hpp> + +#include "../Reveal.hpp" +#include "SpaceModule.hpp" +#include "DepthCamModule.hpp" + +using namespace std; +using namespace glm; + +Module::Module() { + m_depth=0; + m_type="Module"; + m_position=vec3(0.0, 0.0, 0.0); + m_scale=vec3(1.0, 1.0, 1.0); + m_modelScale = vec3(1.0, 1.0, 1.0); + m_parent=NULL; + m_parentMat = mat4(1.0); + m_modelMat = mat4(1.0); + m_rotMat = mat4(1.0); + m_visible=true; + m_parentVisible=true; + m_upID=-1; + m_visibilityMask=1; + m_texWidth=640; + m_texHeight=480; +} + +void Module::deleteModule() { + vector<Attribute*>::iterator itAtt = m_attributesVec.begin(); + for(; itAtt!=m_attributesVec.end(); ++itAtt) { + (*itAtt)->clearListeners(); + } + if(m_parent!=NULL) { + m_parent->removeChild(this); + } + Reveal::getInstance()->deleteModule(this); +} + +Module::~Module() { + vector<Attribute*>::iterator itAtt = m_attributesVec.begin(); + for(; itAtt!=m_attributesVec.end(); ++itAtt) { + delete (*itAtt); + } + m_attributesVec.clear(); + m_attributesMap.clear(); +} + +void Module::load(xmlNodePtr node) { + //call load on each attribute, from their names + xmlNodePtr attsNode; + for(attsNode=node->children; attsNode; attsNode=attsNode->next){ + if(attsNode->type == XML_ELEMENT_NODE && + !xmlStrcmp(attsNode->name, (const xmlChar *) "Attributes")) { + xmlNodePtr attNode; + for(attNode=attsNode->children; attNode; attNode=attNode->next){ + if(attNode->type == XML_ELEMENT_NODE) { + string nameStr((char*) attNode->name); + if(m_attributesMap.find(nameStr)!=m_attributesMap.end()) { + m_attributesMap[nameStr]->load(attNode); + } + } + } + } + } +} + +xmlNodePtr Module::save(xmlNodePtr parentNode) { + xmlNodePtr newNode; + if(parentNode==NULL) { + newNode = xmlNewNode(NULL, BAD_CAST m_type.c_str()); + } + else { + newNode = xmlNewChild(parentNode, NULL, + BAD_CAST m_type.c_str(), NULL); + } + xmlNodePtr attsNode = xmlNewChild(newNode, NULL, + BAD_CAST "Attributes", NULL); + vector<Attribute*>::iterator itAtt = m_attributesVec.begin(); + for(; itAtt!=m_attributesVec.end(); ++itAtt) { + (*itAtt)->save(attsNode); + } + return newNode; +} + +void Module::setName(const std::string& name) { + m_name=name; + Reveal::getInstance()->refreshModules(); +} + +void Module::setVisibleFrom(const std::string& visibleFrom) { + //find space or proj, get visibility bit + setVisibilityMask(Reveal::getInstance()->getVisibilityMask(visibleFrom)); +} + +void Module::setVisibleFromList(vector<string>& modVec) { + map<string, Attribute*>::iterator itAtt + = m_attributesMap.find("visible_from"); + if(itAtt!=m_attributesMap.end()) { + itAtt->second->editStringValuesChoices().assign(1, modVec); + } +} + +void Module::setRevealedBy(const std::string& by) { + m_revealedBy=0; + if(!by.compare("none") || !by.compare("0") || by.length()==0) { + m_revealedBy=0; + } + else if(!by.compare("all")) { + m_revealedBy=numeric_limits<int>::max(); + } + else { + //get all markers + string markStr=by; + while(markStr.length()>0) { + size_t pos=markStr.find_first_of('|'); + string subStr = markStr.substr(0,pos); + istringstream iss(subStr); + int mark; + iss>>mark; + m_revealedBy |= 1 << (mark); + markStr = (pos==string::npos)?"":markStr.substr(pos+1); + } + } + m_revealedBy=std::max(0,m_revealedBy); +} + +void Module::setPosition(const float& posX, + const float& posY, + const float& posZ) { + m_position = vec3(posX, posY, posZ); + updateModelMatrix(); +} + +void Module::setScale(const float& scaX, + const float& scaY, + const float& scaZ) { + m_scale= vec3(scaX, scaY, scaZ); + updateModelMatrix(); +} + +void Module::setRotation(const float& rotX, + const float& rotY, + const float& rotZ) { + m_rotEuler = vec3(rotX/180.0*M_PI, rotZ/180.0*M_PI, rotY/180.0*M_PI); + m_rotQuat = toQuat(orientate3(m_rotEuler)); + m_rotMat = toMat4(m_rotQuat); + vector<float> quatVec(4, 0.0); + quatVec[0]=m_rotQuat[0]; + quatVec[1]=m_rotQuat[1]; + quatVec[2]=m_rotQuat[2]; + quatVec[3]=m_rotQuat[3]; + m_attributesMap["quaternion"]->initFloats(quatVec); + updateModelMatrix(); +} + +void Module::setQuaternion(const float& rotX, + const float& rotY, + const float& rotZ, + const float& rotW) { + m_rotQuat = quat(rotX, rotY, rotZ, rotW); + m_rotEuler = eulerAngles(m_rotQuat); + m_rotMat = toMat4(m_rotQuat); + vector<float> rotVec(3, 0.0); + rotVec[0]=m_rotEuler[0]/M_PI*180.0; + rotVec[1]=m_rotEuler[1]/M_PI*180.0; + rotVec[2]=m_rotEuler[2]/M_PI*180.0; + m_attributesMap["rotation"]->initFloats(rotVec); + updateModelMatrix(); +} + +void Module::setFollowMarker(const int& markID) { + if(markID>0) { + //if not already registered + //subscribe to marker update in all depthcams of all spaces + if(m_markerListeners.size()==0) { + const std::vector<SpaceModule*>& spaces = Reveal::getInstance() + ->getSpaces()->getSpaces(); + for(SpaceModule* sp:spaces) { + unsigned int nbcams = sp->getNbDepthCamModules(); + for(unsigned int i=0; i<nbcams; ++i) { + Attribute* attr + = dynamic_cast<SpaceModule*>(sp) + ->getDepthCamModule(i) + ->getAttribute("marker_output"); + if(attr) { + //create a listener for that camera + m_markerListeners.push_back(MarkerListener(this)); + + //register that listener + attr->addListener(&m_markerListeners.back()); + } + } + } + } + //update marker number + for(auto& mark:m_markerListeners) { + mark.setMarkerID(markID); + } + } + else { //unsubscribe all + for(auto& mark:m_markerListeners) { + mark.getAttribute()->removeListener(&mark); + } + m_markerListeners.clear(); + } +} + +void Module::setModelMat(const glm::mat4& mat) { + m_modelMat=mat; + m_invModelMat = inverse(m_modelMat); + + glm::vec3 sk; + glm::vec4 pers; + glm::decompose(m_modelMat, m_scale, m_rotQuat, m_position, sk, pers); + m_rotMat = toMat4(m_rotQuat); + m_rotEuler = eulerAngles(m_rotQuat); + m_modelScale = m_scale; + + + vector<float> posVec(3, 0.0); + posVec[0]=m_position[0];posVec[1]=m_position[1];posVec[2]=m_position[2]; + m_attributesMap["position"]->initFloats(posVec); + vector<float> rotVec(3, 0.0); + rotVec[0]=m_rotEuler[0]/M_PI*180.0; + rotVec[1]=m_rotEuler[1]/M_PI*180.0; + rotVec[2]=m_rotEuler[2]/M_PI*180.0; + m_attributesMap["rotation"]->initFloats(rotVec); + vector<float> quatVec(4, 0.0); + quatVec[0]=m_rotQuat[0];quatVec[1]=m_rotQuat[1]; + quatVec[2]=m_rotQuat[2];quatVec[3]=m_rotQuat[3]; + m_attributesMap["quaternion"]->initFloats(quatVec); +} + +void Module::updateModelMatrix() { + mat4 transMat = translate(m_position); + mat4 scaleMat = scale(m_scale); + m_modelMat = m_parentMat * transMat * m_rotMat * scaleMat; + m_invModelMat = inverse(m_modelMat); + for(int i=0; i<3; i++) { + m_modelScale[i] = length(vec3(m_modelMat[i][0], + m_modelMat[i][1], + m_modelMat[i][2])); + } + + if(m_attributesMap.find("absolute_position")!=m_attributesMap.end()) { + vector<float> absP(3,0); + absP[0]=m_modelMat[3][0]; + absP[1]=m_modelMat[3][1]; + absP[2]=m_modelMat[3][2]; + m_attributesMap["absolute_position"]->setFloats(absP); + } +} + +void Module::listModulesAndAttributes(const std::string& parentName, + std::map<std::string, Module*>& mods, + std::map<std::string, Attribute*>& atts) { + m_fullName = parentName+"/"+m_name; + mods[m_fullName]=this; + vector<Attribute*>::iterator itAtt = m_attributesVec.begin(); + for(; itAtt!=m_attributesVec.end(); ++itAtt) { + std::string fullName = parentName+"/"+m_name+"/"+(*itAtt)->getName(); + atts[fullName] = (*itAtt); + (*itAtt)->setFullName(fullName); + } +} + +void Module::addNameAttribute() { + addAttribute(new Attribute("name", + Attribute::STRING_ATTRIBUTE, + nameCallback, this, 1)); + m_attributesMap["name"]->setStrings(vector<string>(1, m_name)); +} + +void Module::addRemoveAttribute() { + addAttribute(new Attribute("remove", + Attribute::ACTION_ATTRIBUTE, + removeCallback, this)); +} + +void Module::addTransformationAttributes() { + addAttribute(new Attribute("position", + Attribute::FLOAT_ATTRIBUTE, + positionCallback, this, 3)); + addAttribute(new Attribute("scale", + Attribute::FLOAT_ATTRIBUTE, + scaleCallback, this, 3)); + addAttribute(new Attribute("quaternion", + Attribute::FLOAT_ATTRIBUTE, + quaternionCallback, this, 4)); + addAttribute(new Attribute("rotation", + Attribute::FLOAT_ATTRIBUTE, + rotationCallback, this, 3)); + addAttribute(new Attribute("absolute_position", + Attribute::FLOAT_ATTRIBUTE, + absPositionCallback, this, 3, + Attribute::HIDDEN)); + m_attributesMap["scale"]->setFloats(vector<float>(3,1.0)); +} + +void Module::addVisibleAttribute() { + addAttribute(new Attribute("visible", + Attribute::BOOL_ATTRIBUTE, + visibleCallback, this, 1)); + m_attributesMap["visible"]->initBools(vector<bool>(1, true)); +} + +void Module::addVisibleFromAttribute() { + addAttribute(new Attribute("visible_from", + Attribute::STRING_ATTRIBUTE, + visibleFromCallback, this, 1)); + m_attributesMap["visible_from"]->initStrings(vector<string>(1, "all")); +} + +void Module::addRevealedByAttribute() { + addAttribute(new Attribute("revealed_by", + Attribute::STRING_ATTRIBUTE, + revealedByCallback, this, 1)); +/* + m_revealedBys.push_back("all"); + m_revealedBys.push_back("1"); + m_revealedBys.push_back("2"); + m_revealedBys.push_back("3"); + m_revealedBy=0; + m_attributesMap["revealed_by"]->editStringValuesChoices() + .assign(1,m_revealedBys); +*/ + m_attributesMap["revealed_by"]->setStrings(vector<string>(1, "all")); +} + +void Module::addFollowMarkerAttribute() { + addAttribute(new Attribute("follow_marker", + Attribute::INT_ATTRIBUTE, + followMarkerCallback, this, 1)); + +} + +void Module::getQuatFromTwoVecs(glm::quat& q, glm::vec3& from, glm::vec3& to) { + glm::vec3 start = normalize(from); + glm::vec3 dest = normalize(to); + + float cosTheta = dot(start, dest); + glm::vec3 rotationAxis; + + if(cosTheta < -1 + 0.001f) { + rotationAxis = cross(glm::vec3(0.0f, 0.0f, 1.0f), start); + if(glm::length2(rotationAxis) < 0.01) { + rotationAxis = cross(glm::vec3(1.0f, 0.0f, 0.0f), start); + } + rotationAxis = normalize(rotationAxis); + q=glm::angleAxis(glm::radians(180.0f), rotationAxis); + return; + } + + rotationAxis = cross(start, dest); + + float s = sqrt( (1+cosTheta)*2 ); + float invs = 1 / s; + + q[0]=s * 0.5f; + q[1]=rotationAxis.x * invs; + q[2]=rotationAxis.y * invs; + q[3]=rotationAxis.z * invs; + return; +} + +//----------------------------Marker Listener--------------------------------- + +MarkerListener::MarkerListener(Module* mod) : Listener() { + m_mod=mod; + m_listenerType = "Marker"; +} + +MarkerListener::~MarkerListener() { + +} + +void MarkerListener::update(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues) { + if(floatValues[0]==m_markerID && floatValues[1]>0) { + m_mod->getAttribute("position") + ->setFloats(vector<float>{floatValues[2], + floatValues[3], + floatValues[4]}); + m_mod->getAttribute("quaternion") + ->setFloats(vector<float>{floatValues[5], + floatValues[6], + floatValues[7], + floatValues[8]}); + } +} + diff --git a/src/modules/Module.hpp b/src/modules/Module.hpp new file mode 100644 index 0000000..8d91014 --- /dev/null +++ b/src/modules/Module.hpp @@ -0,0 +1,238 @@ +/*************************************************************************** + * Module.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef Module_h +#define Module_h + +#include "Attribute.hpp" + +#define GLM_ENABLE_EXPERIMENTAL + +#include <GL/glew.h> +#include <GLFW/glfw3.h> +#include <glm/vec3.hpp> +#include <glm/vec4.hpp> +#include <glm/mat4x4.hpp> +#include <glm/gtc/quaternion.hpp> +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtx/transform.hpp> +#include <glm/gtc/type_ptr.hpp> + +class GroupModule; +class MarkerListener; + +class Module { + public: + Module(); + virtual ~Module(); + + virtual void draw(){} + + virtual void load(xmlNodePtr node); + virtual xmlNodePtr save(xmlNodePtr parentNode); + + void setParent(GroupModule* groupmod){m_parent=groupmod;} + void setChildID(const unsigned int& id){m_childID=id;} + const unsigned int& getChildID(){return m_childID;} + virtual void getSubTree(std::vector<Module*>& children) { + children.push_back(this); + } + + inline unsigned int getNbAttributes(){return m_attributesVec.size();} + inline Attribute* getAttribute(const unsigned int& attr) { + return m_attributesVec[attr]; + } + inline Attribute* getAttribute(const std::string& attr) { + return m_attributesMap[attr]; + } + inline std::vector<Attribute*>& editAttributes() { + return m_attributesVec; + } + inline void addAttribute(Attribute* attr) { + m_attributesMap[attr->getName()]=attr; + m_attributesVec.push_back(attr); + } + static void nameCallback(Module* mod, + const std::vector<std::string>& vals) { + static_cast<Module*>(mod)->setModuleName(vals[0]); + } + static void removeCallback(Module* mod) { + static_cast<Module*>(mod)->deleteModule(); + } + virtual void deleteModule(); + static void positionCallback(Module* mod, + const std::vector<float>& vals) { + static_cast<Module*>(mod)->setPosition(vals[0], + vals[1], + vals[2]); + } + virtual void setPosition(const float& posX, + const float& posY, + const float& posZ); + static void absPositionCallback(Module* mod, + const std::vector<float>& vals) {} + + static void scaleCallback(Module* mod, + const std::vector<float>& vals) { + static_cast<Module*>(mod)->setScale(vals[0], + vals[1], + vals[2]); + } + virtual void setScale(const float& scaX, + const float& scaY, + const float& scaZ); + static void rotationCallback(Module* mod, + const std::vector<float>& vals) { + static_cast<Module*>(mod)->setRotation(vals[0], + vals[1], + vals[2]); + } + virtual void setRotation(const float& rotX, + const float& rotY, + const float& rotZ); + static void quaternionCallback(Module* mod, + const std::vector<float>& vals) { + static_cast<Module*>(mod)->setQuaternion(vals[0], + vals[1], + vals[2], + vals[3]); + } + virtual void setQuaternion(const float& rotX, + const float& rotY, + const float& rotZ, + const float& rotW); + + const glm::mat4& getModelMat(){return m_modelMat;} + virtual void setModelMat(const glm::mat4& mat); + + static void followMarkerCallback(Module* mod, + const std::vector<int>& vals) { + static_cast<Module*>(mod)->setFollowMarker(vals[0]); + } + virtual void setFollowMarker(const int& mark); + + static void visibleCallback(Module* mod, + const std::vector<bool>& vals) { + static_cast<Module*>(mod)->setVisible(vals[0]); + } + + static void visibleFromCallback(Module* mod, + const std::vector<std::string>& vals) { + static_cast<Module*>(mod)->setVisibleFrom(vals[0]); + } + + static void revealedByCallback(Module* mod, + const std::vector<std::string>& vals) { + static_cast<Module*>(mod)->setRevealedBy(vals[0]); + } + void setRevealedBy(const std::string& by); + + inline const std::string& getName(){return m_name;} + void setName(const std::string& val); + inline virtual void setModuleName(const std::string& val){setName(val);} + inline const std::string& getType(){return m_type;} + inline void setDepth(const unsigned int& depth){m_depth=depth;} + inline const unsigned int& getDepth(){return m_depth;} + inline const std::string& getFullName(){return m_fullName;} + + inline virtual void setVisible(bool vis){m_visible=vis;} + inline virtual void setParentVisible(bool pvis){m_parentVisible=pvis;} + inline bool isVisible(){return m_visible && m_parentVisible;} + void setVisibleFrom(const std::string& visibleFrom); + void setVisibleFromList(std::vector<std::string>& modVec); + virtual void getVisibleFromList(std::vector<std::string>& modVec, + std::map<std::string, int>& modMap){} + inline const int& getVisibilityMask(){return m_visibilityMask;} + inline void setVisibilityMask(int mask){m_visibilityMask=mask;} + + virtual void listModulesAndAttributes(const std::string& parentName, + std::map<std::string, Module*>& mods, + std::map<std::string, Attribute*>& atts); + + inline void setParentMatrix(const glm::mat4& mat){m_parentMat=mat;} + virtual void updateModelMatrix(); + + virtual void gotAttributeListenersUpdate(Attribute*){} + + virtual void addNameAttribute(); + virtual void addRemoveAttribute(); + virtual void addTransformationAttributes(); + virtual void addVisibleAttribute(); + virtual void addVisibleFromAttribute(); + virtual void addRevealedByAttribute(); + virtual void addFollowMarkerAttribute(); + + inline void setUpID(const unsigned int& id){m_upID=id;} + inline const int& getUpID(){return m_upID;} + virtual void update(const int& timeDiffMs){} + + protected: + void getQuatFromTwoVecs(glm::quat& q, glm::vec3& from, glm::vec3& to); + + protected: + std::string m_name; + std::string m_fullName; + std::string m_type; + bool m_visible; + bool m_parentVisible; + int m_visibilityMask; + unsigned int m_depth; + GroupModule* m_parent; + unsigned int m_childID; + glm::mat4 m_transform; + std::map<std::string, Attribute*> m_attributesMap; + std::vector<Attribute*> m_attributesVec; + std::vector<std::string> m_revealedBys; + int m_revealedBy; + int m_upID; + glm::vec3 m_position; + glm::vec3 m_scale; + glm::quat m_rotQuat; + glm::vec3 m_rotEuler; + glm::mat4 m_rotMat; + glm::mat4 m_modelMat; + glm::mat4 m_invModelMat; + glm::mat4 m_parentMat; + glm::vec3 m_modelScale; + int m_texWidth; + int m_texHeight; + + std::vector<MarkerListener> m_markerListeners; +}; + +class MarkerListener : public Listener { + public : + MarkerListener(Module* mod); + virtual ~MarkerListener(); + virtual void update(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues); + inline void setMarkerID(const int& m){m_markerID=m;} + private: + int m_markerID; + Module* m_mod; +}; + + +#endif diff --git a/src/modules/OutputManagerModule.cpp b/src/modules/OutputManagerModule.cpp new file mode 100644 index 0000000..60fbd41 --- /dev/null +++ b/src/modules/OutputManagerModule.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * OutputManagerModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "../Reveal.hpp" +#include "OutputManagerModule.hpp" + +using namespace std; + +OutputManagerModule::OutputManagerModule():GroupModule() { + m_type="OutputManager"; + m_name="outputs"; + addAttribute(new Attribute("add_osc_output", + Attribute::ACTION_STRING_ATTRIBUTE, + addOscOutputCallback, this, 1, + Attribute::LOCAL)); + m_attributesMap["add_osc_output"]->initStrings(vector<string>(1, "osc")); + addAttribute(new Attribute("add_pd_output", + Attribute::ACTION_STRING_ATTRIBUTE, + addPdOutputCallback, this, 1, + Attribute::LOCAL)); + m_attributesMap["add_pd_output"]->initStrings(vector<string>(1, "patch")); +} + +OutputManagerModule::~OutputManagerModule() { + +} + +void OutputManagerModule::addOscOutput(const string& name) { + OutputOscModule *chi = new OutputOscModule(); + addChild(chi); + chi->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + +void OutputManagerModule::addPdOutput(const string& name) { + OutputPdModule *chi = new OutputPdModule(); + addChild(chi); + chi->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + diff --git a/src/modules/OutputManagerModule.hpp b/src/modules/OutputManagerModule.hpp new file mode 100644 index 0000000..2bb7ed2 --- /dev/null +++ b/src/modules/OutputManagerModule.hpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * OutputManagerModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef OutputManagerModule_h +#define OutputManagerModule_h + +#include "GroupModule.hpp" + +#include "OutputOscModule.hpp" +#include "OutputPdModule.hpp" + +class OutputManagerModule : public GroupModule { + public : + OutputManagerModule(); + virtual ~OutputManagerModule(); + + static void addOscOutputCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<OutputManagerModule*>(mod)->addOscOutput(vals[0]); + } + void addOscOutput(const std::string&); + static void addPdOutputCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<OutputManagerModule*>(mod)->addPdOutput(vals[0]); + } + void addPdOutput(const std::string&); + + private : + + +}; + +#endif + diff --git a/src/modules/OutputOscModule.cpp b/src/modules/OutputOscModule.cpp new file mode 100644 index 0000000..819cdb0 --- /dev/null +++ b/src/modules/OutputOscModule.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * OutputOscModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "OutputOscModule.hpp" +#include <iostream> + +using namespace std; + +OutputOscModule::OutputOscModule(): Module() { + m_type="OutputOsc"; + m_name="osc"; + addNameAttribute(); + + //string attribute for ip adress + addAttribute(new Attribute("address", + Attribute::STRING_ATTRIBUTE, + addressCallback, this, 1, Attribute::LOCAL)); + m_attributesMap["address"]->setStrings(vector<string>(1, "127.0.0.1")); + + //int attribute for port + addAttribute(new Attribute("port", + Attribute::INT_ATTRIBUTE, + portCallback, this, 1, Attribute::LOCAL)); + m_attributesMap["port"]->setInts(vector<int>(1, 7000)); + +} + +OutputOscModule::~OutputOscModule() { + +} + +void OutputOscModule::setAddress(const string& add) { + m_address=add; +} + +void OutputOscModule::setPort(const int& port) { + m_port=port; +} + diff --git a/src/modules/OutputOscModule.hpp b/src/modules/OutputOscModule.hpp new file mode 100644 index 0000000..247f01e --- /dev/null +++ b/src/modules/OutputOscModule.hpp @@ -0,0 +1,53 @@ +/*************************************************************************** + * OutputOscModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef OutputOscModule_h +#define OutputOscModule_h + +#include "Module.hpp" + +class OutputOscModule : public Module { + public : + OutputOscModule(); + virtual ~OutputOscModule(); + + static void addressCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<OutputOscModule*>(mod)->setAddress(vals[0]); + } + void setAddress(const std::string& add); + + static void portCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<OutputOscModule*>(mod)->setPort(vals[0]); + } + void setPort(const int& add); + + private : + std::string m_address; + int m_port; + +}; + +#endif + diff --git a/src/modules/OutputPdModule.cpp b/src/modules/OutputPdModule.cpp new file mode 100644 index 0000000..3664601 --- /dev/null +++ b/src/modules/OutputPdModule.cpp @@ -0,0 +1,37 @@ +/*************************************************************************** + * OutputPdModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "OutputPdModule.hpp" + +using namespace std; + +OutputPdModule::OutputPdModule():Module() { + m_type="OutputPd"; + m_name="pd"; + addNameAttribute(); + + //add pd file attribute +} + +OutputPdModule::~OutputPdModule() { + +} diff --git a/src/modules/OutputPdModule.hpp b/src/modules/OutputPdModule.hpp new file mode 100644 index 0000000..0957d5f --- /dev/null +++ b/src/modules/OutputPdModule.hpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * OutputPdModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef OutputPdModule_h +#define OutputPdModule_h + +#include "Module.hpp" + +class OutputPdModule : public Module { + public : + OutputPdModule(); + virtual ~OutputPdModule(); + + private : + + +}; + +#endif diff --git a/src/modules/PreviewModule.cpp b/src/modules/PreviewModule.cpp new file mode 100644 index 0000000..2335286 --- /dev/null +++ b/src/modules/PreviewModule.cpp @@ -0,0 +1,315 @@ +/*************************************************************************** + * PreviewModule.cpp + * Part of PreviewModule + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "PreviewModule.hpp" + +#include <iostream> +#include "../Reveal.hpp" +#include "../geoms/BoxGeometry.hpp" +#include "../geoms/SphereGeometry.hpp" +#include <glm/gtc/matrix_transform.hpp> + +using namespace std; +using namespace glm; + +PreviewModule::PreviewModule():Module() { + m_type="Preview"; + m_name="preview"; + m_active=true; + + addAttribute(new Attribute("active", + Attribute::BOOL_ATTRIBUTE, + activeCallback, this, 1, + Attribute::LOCAL)); + addAttribute(new Attribute("look_at", + Attribute::FLOAT_ATTRIBUTE, + lookAtCallback, this, 3)); + addAttribute(new Attribute("from", + Attribute::FLOAT_ATTRIBUTE, + eyePositionCallback, this, 3)); + + m_attributesMap["active"]->initBools(vector<bool>(1, true)); + + //initialize matrices + vector<float> initPos(3,0); + m_attributesMap["look_at"]->setFloats(initPos); + initPos[2]=-700.0; + m_attributesMap["from"]->setFloats(initPos); + updateViewProjMatrix(); + + //create preview window + m_previewWindow = glfwCreateWindow(600, 480, "Revil - Preview", NULL, NULL); + if (!m_previewWindow) { + glfwTerminate(); + exit(EXIT_FAILURE); + } + glfwPollEvents(); + glfwSetWindowSize(m_previewWindow, 640, 480); + + glfwSetWindowUserPointer(m_previewWindow, this); + glfwSetMouseButtonCallback(m_previewWindow, + (GLFWmousebuttonfun)previewMouseBtnCB); + glfwSetCursorPosCallback(m_previewWindow, + (GLFWcursorposfun)previewMousePosCB); + glfwSetScrollCallback(m_previewWindow, + (GLFWscrollfun)previewMouseScrollCB); + + Reveal::getInstance()->addContextHandler(this); + + m_initialized=false; +} + +PreviewModule::~PreviewModule() {} + +void PreviewModule::load(xmlNodePtr node) { + Module::load(node); +} + +void PreviewModule::draw() { + //set context for window + glfwMakeContextCurrent(m_previewWindow); + + //initialize + if(!m_initialized) { + initGL(); + m_initialized=true; + } + + //clear window + int width, height; + glfwGetFramebufferSize(m_previewWindow, &width, &height); + glViewport(0, 0, width, height); + glClearColor(0.1, 0.1, 0.1, 1); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //load preview shader + glUseProgram(m_program); + + //set view/projection uniforms + glUniformMatrix4fv(m_uniforms[Reveal::VIEWPROJMAT], 1, + GL_FALSE, value_ptr(m_viewProjMat)); + + //draw all scene geometry and their connected shape/ modules + const vector<Geometry*>& sceneGeoms = Reveal::getInstance()->getGeoms(); + vector<Geometry*>::const_iterator itScGeom=sceneGeoms.begin(); + for(; itScGeom!=sceneGeoms.end(); ++itScGeom) { + (*itScGeom)->draw(m_contextHandlerID, + Reveal::PREVIEWPROG, + m_uniforms, + 1); + } + + + //for each space from reveal + //draw all projectors and depth cameras + + + glfwSwapBuffers(m_previewWindow); +} + +void PreviewModule::mouseBtnCB(const int& btn, const int& action, + const int& mods) { + switch(action) { + case GLFW_PRESS : { + m_mouseStartPosX = m_mousePosX; + m_mouseStartPosY = m_mousePosY; + switch(btn) { + case 0: { + m_control=MOVING; + }break; + case 1: { + m_control=ORBITING; + }break; + case 2: { + m_control=TURNING; + }break; + } + }break; + case GLFW_RELEASE: { + m_control=NONE; + }break; + default:break; + } +} + +void PreviewModule::mousePosCB(const double& x, const double& y) { + m_mousePosX=x; + m_mousePosY=y; + //FIXME recompute lookAt based on eye pos and vector + switch(m_control) { + case TURNING : { + + } break; + case MOVING : { + float diffX = (m_mousePosX-m_mouseStartPosX)/1; + float diffY = (m_mousePosY-m_mouseStartPosY)/1; + setEyePosition(m_eyePos[0]+diffX, m_eyePos[1]+diffY, m_eyePos[2]); + setLookAt(m_lookAt[0]+diffX, m_lookAt[1]+diffY, m_lookAt[2]); + m_mouseStartPosX=m_mousePosX; + m_mouseStartPosY=m_mousePosY; + } break; + case ORBITING : { + + } break; + default:break; + } +} + +void PreviewModule::mouseScrollCB(const double& x, const double& y) { + +} + +void PreviewModule::initGL() { + #ifdef OSX + glewExperimental = GL_TRUE; + #endif + if(glewInit()!=GLEW_OK) { + cout<<"Could not initialize glew for Preview Window"<<endl; + } + + const GLubyte* renderer = glGetString (GL_RENDERER); + const GLubyte* version = glGetString (GL_VERSION); + cout<<"Renderer: "<<renderer<<endl; + cout<<"OpenGL version supported "<<version<<endl; + + + + //create preview program + const char * vertSource = { + #ifdef GL42 + "#version 430 \n" + #else + "#version 410 \n" + #endif + "\n" + "in vec3 vertex;\n" + "in vec2 texCoords;\n" + "\n" + "uniform mat4 modelMat;\n" + "uniform mat4 viewProjMat;\n" + "\n" + "out vec2 uvCoords;\n" + "out float light;\n" + "\n" + "void main(void) {\n" + " gl_Position = viewProjMat*modelMat*vec4(vertex, 1.0);\n" + " light = distance(\n" + " vec3(0,0,0),\n" + " vec3(modelMat[3][0], modelMat[3][1], modelMat[3][2]));\n" + " uvCoords=texCoords;\n" + "}\n"}; + const char * fragSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + "\n" + "in vec2 uvCoords;\n" + "in float light;\n" + "\n" + "uniform vec3 shapeColor;\n" +#ifdef GL42 + "layout(binding=3) uniform sampler2D surfaceTex;\n" +#else + "uniform sampler2D surfaceTex;\n" +#endif + "\n" + "out vec4 color;\n" + "\n" + "void main(void) {\n" + " float pixZ=pow(gl_FragCoord.z,3);\n" + //" float pixZ=light;\n" + " color = vec4(shapeColor.x*pixZ, shapeColor.y*pixZ,\n" + " shapeColor.z*pixZ, 1);\n" + //" color = vec4(uvCoords,0,1);\n" + "}\n"}; + m_program = Reveal::getInstance()->createProgram(vertSource, fragSource); + m_uniforms[Reveal::VIEWPROJMAT] + = glGetUniformLocation(m_program, "viewProjMat"); + m_uniforms[Reveal::MODELMAT] + = glGetUniformLocation(m_program, "modelMat"); + m_uniforms[Reveal::SHAPECOLOR] + = glGetUniformLocation(m_program, "shapeColor"); + m_uniforms[Reveal::SURFACETEX] + = glGetUniformLocation(m_program, "surfaceTex"); +} + +void PreviewModule::setEyePosition(const float& x, + const float& y, + const float& z) { + m_eyePos = vec3(x, y, z); + updateViewProjMatrix(); +} + +void PreviewModule::setLookAt(const float& x, + const float& y, + const float& z) { + m_lookAt = vec3(x, y, z); + updateViewProjMatrix(); +} + + +void PreviewModule::updateViewProjMatrix() { + m_viewMat = lookAt(m_eyePos, + m_lookAt, + vec3(0.0, 1.0, 0.0)); + m_projMat = perspective(45.0, 4.0/3.0, 100.0, 10000.0); + m_viewProjMat = m_projMat*m_viewMat; +} + +/* + float width = m_screenDim.x(); + float height = m_screenDim.y(); + float dl=width/2.0+m_eyePos.x(); + float db=m_eyePos.y(); + float f=-m_near/(fabs(m_eyePos.z())+1); + Reveal::getInstance()->getPreviewCamera() + ->setProjectionMatrixAsFrustum((width-dl)*f,-dl*f, + (height-db)*f, -db*f, + m_near, m_far); + Matrixf rotMat = Matrixf::rotate(m_screenRot[0], Vec3f(1, 0, 0), + m_screenRot[1], Vec3f(0, 1, 0), + m_screenRot[2], Vec3f(0, 0, 1)); + Vec3f eyeToWPos = m_screenPos + m_eyePos*rotMat; + Vec3f lookAt = m_screenPos+(m_eyePos+Vec3f(0, 0, 1))*rotMat; + Matrixf viewMat; + viewMat.makeLookAt(eyeToWPos, + lookAt, + Vec3f(0,1,0)); + osg::Matrixf glCoordsMat(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + viewMat=viewMat*glCoordsMat; + Reveal::getInstance()->getPreviewCamera()->setViewMatrix(viewMat); +} +*/ + diff --git a/src/modules/PreviewModule.hpp b/src/modules/PreviewModule.hpp new file mode 100644 index 0000000..3c41648 --- /dev/null +++ b/src/modules/PreviewModule.hpp @@ -0,0 +1,108 @@ +/*************************************************************************** + * PreviewModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef PreviewModule_h +#define PreviewModule_h + +#include "Module.hpp" +#include "../Reveal.hpp" + +class Geometry; + +class PreviewModule: public Module, public ContextHandler { + public: + PreviewModule(); + virtual ~PreviewModule(); + virtual void draw(); + + virtual void load(xmlNodePtr node); + + static void previewMouseBtnCB(GLFWwindow* win, int btn, + int action, int mods) { + static_cast<PreviewModule*>(glfwGetWindowUserPointer(win)) + ->mouseBtnCB(btn, action, mods); + } + void mouseBtnCB(const int& btn, const int& action, const int& mods); + + static void previewMousePosCB(GLFWwindow* win, int btn, + double x, double y) { + static_cast<PreviewModule*>(glfwGetWindowUserPointer(win)) + ->mousePosCB(x, y); + } + void mousePosCB(const double& x, const double& y); + + static void previewMouseScrollCB(GLFWwindow* win, int btn, + double x, double y) { + static_cast<PreviewModule*>(glfwGetWindowUserPointer(win)) + ->mouseScrollCB(x, y); + } + void mouseScrollCB(const double& x, const double& y); + + static void activeCallback(Module* mod, + const std::vector<bool>& vals) { + static_cast<PreviewModule*>(mod)->setActive(vals[0]); + } + inline void setActive(bool active) {m_active=active;} + static void eyePositionCallback(Module* mod, + const std::vector<float>& vals) { + static_cast<PreviewModule*>(mod)->setEyePosition(vals[0], + vals[1], + vals[2]); + } + static void lookAtCallback(Module* mod, + const std::vector<float>& vals) { + static_cast<PreviewModule*>(mod)->setLookAt(vals[0], + vals[1], + vals[2]); + } + + void setEyePosition(const float& x, const float& y, const float& z); + void setLookAt(const float& x, const float& y, const float& z); + void updateViewProjMatrix(); + inline GLFWwindow* getWindow(){return m_previewWindow;} + + private: + void initGL(); + + protected: + bool m_active; + GLFWwindow* m_previewWindow; + glm::vec3 m_eyePos; + glm::vec3 m_lookAt; + float m_near; + float m_far; + glm::mat4 m_viewMat; + glm::mat4 m_projMat; + glm::mat4 m_viewProjMat; + GLint m_viewProjUniform; + bool m_initialized; + GLint m_program; + std::map<Reveal::REVIL_UNIFORM, GLint> m_uniforms; + std::vector<Geometry*> m_geometries; + enum {NONE, TURNING, ORBITING, MOVING} m_control; + float m_mousePosX, m_mousePosY; + float m_mouseStartPosX, m_mouseStartPosY; +}; + +#endif + diff --git a/src/modules/ProjectorModule.cpp b/src/modules/ProjectorModule.cpp new file mode 100644 index 0000000..d337fd0 --- /dev/null +++ b/src/modules/ProjectorModule.cpp @@ -0,0 +1,2419 @@ +/*************************************************************************** + * ProjectorModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 130, Boston, MA 02111-1307, USA. + */ + +/*//////////// +Calibration heavily relies on code from : +https://github.com/Kj1/ofxProjectorKinectCalibration +https://github.com/kylemcdonald/ofxCv +*///////////////////// + +#include "ProjectorModule.hpp" + +#include <iostream> + +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/calib3d/calib3d.hpp" + +#include "../Reveal.hpp" +#include "DepthCamModule.hpp" +#include "SpaceModule.hpp" +#include "RevealedModule.hpp" + + +using namespace std; +using namespace glm; +using namespace cv; + +ProjectorModule::ProjectorModule(): Module() { + m_type="Projector"; + m_name="projector"; + + m_space=NULL; + m_width=640; + m_height=480; + m_posX=0; + m_posY=0; + m_processOutput=true; + m_active=true; + m_postFilter=0; + m_transparentBackground=false; + + //create window + m_projWindow = glfwCreateWindow(m_width, m_height, + "Revil - Projector", NULL, NULL); + if(!m_projWindow) { + glfwTerminate(); + exit(EXIT_FAILURE); + } + m_rttWidth=1920; + m_rttHeight=1080; + glfwSetWindowUserPointer(m_projWindow, this); + glfwSetWindowSizeCallback(m_projWindow, windowSizeCallback); + glfwSetWindowPosCallback(m_projWindow, windowPositionCallback); + glfwSetFramebufferSizeCallback(m_projWindow, framebufferSizeCallback); + glfwSetInputMode(m_projWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + addNameAttribute(); + addRemoveAttribute(); + addAttribute(new Attribute("active", + Attribute::BOOL_ATTRIBUTE, + activeCallback, this, 1, + Attribute::LOCAL)); + addAttribute(new Attribute("window_dimensions", + Attribute::INT_ATTRIBUTE, + windowDimensionsCallback, this, 4, + Attribute::LOCAL)); + addAttribute(new Attribute("fullscreen_monitor", + Attribute::STRING_ATTRIBUTE, + fullscreenMonitorCallback, this, 1, + Attribute::LOCAL)); + addAttribute(new Attribute("view_matrix", + Attribute::FLOAT_ATTRIBUTE, + viewMatrixCallback, this, 16, + Attribute::HIDDEN)); + addAttribute(new Attribute("projection_matrix", + Attribute::FLOAT_ATTRIBUTE, + projectionMatrixCallback, this, 16, + Attribute::HIDDEN)); + + addAttribute(new Attribute("mirrored", + Attribute::BOOL_ATTRIBUTE, + mirroredCallback, this, 1, + Attribute::LOCAL)); + + addTransformationAttributes(); + m_attributesMap["scale"]->setAccessibility(Attribute::HIDDEN); + vector<float> posVec(3,0); + posVec[2]=-700; + m_attributesMap["position"]->setFloats(posVec); + + addAttribute(new Attribute("attached_to_camera", + Attribute::STRING_ATTRIBUTE, + attachToCamCallback, this, 1, + Attribute::LOCAL)); + addAttribute(new Attribute("calibrate_with_camera", + Attribute::ACTION_STRING_ATTRIBUTE, + calibrateCallback, this, 1, + Attribute::LOCAL, + false)); + addAttribute(new Attribute("output_revealed", + Attribute::BOOL_ATTRIBUTE, + outputRevealedCallback, this, 1, + Attribute::LOCAL)); + addAttribute(new Attribute("post_filter", + Attribute::INT_ATTRIBUTE, + postFilterCallback, this, 1, + Attribute::LOCAL)); + addAttribute(new Attribute("transparent_window", + Attribute::BOOL_ATTRIBUTE, + transparentWindowCallback, this, 1, + Attribute::LOCAL)); + + //initialize attributes + vector<string> labels; + labels.push_back("none"); + m_attributesMap["attached_to_camera"] + ->editStringValuesChoices().assign(1, labels); + m_attributesMap["attached_to_camera"] + ->initStrings(vector<string>(1, labels[0])); + m_attributesMap["calibrate_with_camera"] + ->editStringValuesChoices().assign(1, labels); + m_attributesMap["calibrate_with_camera"] + ->initStrings(vector<string>(1, labels[0])); + refreshMonitors(); + m_attributesMap["fullscreen_monitor"] + ->initStrings(vector<string>(1, "windowed")); + m_attachedToCam=NULL; + m_attributesMap["output_revealed"]->initBools(vector<bool>(1, true)); + m_attributesMap["post_filter"]->initInts(vector<int>(1, 0)); + m_attributesMap["active"]->initBools(vector<bool>(1, true)); + + m_mirrored=false; + + //initialize matrices + m_viewMat = lookAt(vec3(0.0, 0.0, 0.0), + vec3(0.0, 0.0, 1.0), + vec3(0.0, 1.0, 0.0)); + mat4 glCoordsMat(-1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + m_viewMat=glCoordsMat*m_viewMat; + m_attributesMap["view_matrix"]->setFloats(vector<float>( + value_ptr(m_viewMat), + value_ptr(m_viewMat)+16)); + m_projMat = perspective(45.0, 4.0/3.0, 100.0, 10000.0); + m_attributesMap["projection_matrix"]->setFloats(vector<float>( + value_ptr(m_projMat), + value_ptr(m_projMat)+16)); + + vector<int> dims(4,0); + dims[0]=m_posX; + dims[1]=m_posY; + dims[2]=m_width; + dims[3]=m_height; + m_attributesMap["window_dimensions"]->setInts(dims); + + //calibration + m_calibrated=false; + m_patternSquareWidth = 40; + m_patternPosition = Size(100, 200); + m_patternSize = Size(6,4); + m_patternBrightness = 100; + m_patternPosRange = Size(m_width, m_height); + m_patternPosOffset = Size(0,0); + + Reveal::getInstance()->addContextHandler(this); + + m_initialized=false; +} + +ProjectorModule::~ProjectorModule() {} + +void ProjectorModule::draw() { + if(!m_active) { + return; + } + + glfwMakeContextCurrent(m_projWindow); + + if(!m_initialized) { + initGL(); + m_initialized=true; + } + + //slice to texture + glBindFramebuffer(GL_FRAMEBUFFER, m_sliceFBO); + glViewport(0, 0, m_rttWidth, m_rttHeight); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUseProgram(m_programs[Reveal::SLICEPROG]); + glUniform1f(m_uniforms[Reveal::SLICEPROG][Reveal::MIRRORED], + float(m_mirrored)); + glUniformMatrix4fv(m_uniforms[Reveal::SLICEPROG][Reveal::VIEWPROJMAT], 1, + GL_FALSE, value_ptr(m_viewProjMat)); + glUniformMatrix4fv(m_uniforms[Reveal::SLICEPROG][Reveal::VIEWMAT], 1, + GL_FALSE, value_ptr(m_transViewMat)); + const vector<Geometry*>& depthGeoms = m_space->getGeoms(); + vector<Geometry*>::const_iterator itDGeom=depthGeoms.begin(); + for(; itDGeom!=depthGeoms.end(); ++itDGeom) { + (*itDGeom)->draw(m_contextHandlerID, + Reveal::SLICEPROG, + m_uniforms[Reveal::SLICEPROG], + m_visibilityMask); + } + + //select to texture for 3D models only (GEOM_MODEL) + glBindFramebuffer(GL_FRAMEBUFFER, m_selectFBO); + glViewport(0, 0, m_rttWidth, m_rttHeight); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUseProgram(m_programs[Reveal::SELECTPROG]); + glUniform1f(m_uniforms[Reveal::SELECTPROG][Reveal::MIRRORED], + float(m_mirrored)); + glUniformMatrix4fv(m_uniforms[Reveal::SELECTPROG][Reveal::VIEWPROJMAT], 1, + GL_FALSE, value_ptr(m_viewProjMat)); + glUniformMatrix4fv(m_uniforms[Reveal::SELECTPROG][Reveal::VIEWMAT], 1, + GL_FALSE, value_ptr(m_transViewMat)); + glUniform1f(m_uniforms[Reveal::SELECTPROG][Reveal::VIEWPORTWIDTH], + m_rttWidth); + glUniform1f(m_uniforms[Reveal::SELECTPROG][Reveal::VIEWPORTHEIGHT], + m_rttHeight); + glUniform1i(m_uniforms[Reveal::SELECTPROG][Reveal::SLICETEX], 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_sliceRttTex); + const vector<Geometry*>& sceneGeoms = Reveal::getInstance()->getGeoms(); + for(auto& geom : sceneGeoms) { + if(geom->getGeomID()>=Reveal::GEOM_MODEL) { + geom->draw(m_contextHandlerID, + Reveal::SELECTPROG, + m_uniforms[Reveal::SELECTPROG], + m_visibilityMask); + } + } + + + //RENDER TO SCREEN + if(m_postFilter>0) { + glBindFramebuffer(GL_FRAMEBUFFER, m_renderFBO); + glViewport(0, 0, m_rttWidth, m_rttHeight); + } + else { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, m_width, m_height); + } + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glEnable(GL_CULL_FACE); + if(m_mirrored) { + glCullFace(GL_FRONT); + } + else { + glCullFace(GL_BACK); + } + glEnable(GL_BLEND); + glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); + glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE); + glClearColor(0.0, 0.0, 0.0, !m_transparentBackground); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glUseProgram(m_programs[Reveal::RENDERPROG]); + glUniform1f(m_uniforms[Reveal::RENDERPROG][Reveal::MIRRORED], + float(m_mirrored)); + glUniformMatrix4fv(m_uniforms[Reveal::RENDERPROG][Reveal::VIEWPROJMAT], 1, + GL_FALSE, value_ptr(m_viewProjMat)); + glUniformMatrix4fv(m_uniforms[Reveal::RENDERPROG][Reveal::VIEWMAT], 1, + GL_FALSE, value_ptr(m_transViewMat)); + if(m_postFilter>0) { + glUniform1f(m_uniforms[Reveal::RENDERPROG][Reveal::VIEWPORTWIDTH], + m_rttWidth); + glUniform1f(m_uniforms[Reveal::RENDERPROG][Reveal::VIEWPORTHEIGHT], + m_rttHeight); + } + else { + glUniform1f(m_uniforms[Reveal::RENDERPROG][Reveal::VIEWPORTWIDTH], + m_width); + glUniform1f(m_uniforms[Reveal::RENDERPROG][Reveal::VIEWPORTHEIGHT], + m_height); + } + glActiveTexture(GL_TEXTURE0); + glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::SLICETEX], 0); + glBindTexture(GL_TEXTURE_2D, m_sliceRttTex); + glActiveTexture(GL_TEXTURE1); + glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::SELECTTEX], 1); + glBindTexture(GL_TEXTURE_2D, m_selectTex); +#ifdef GL42 + glActiveTexture(GL_TEXTURE7); + glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::OUTPUTTEX], 7); + glBindImageTexture(7, m_outputTex, 0, GL_FALSE, 0, + GL_READ_WRITE, GL_R32UI); + glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::OUTSHAPESIZE], + m_outShapeSize); + glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::OUTDEPTHSIZE], + m_outDepthSize); + glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::OUTNBDEPTH], + m_outNbDepth); +#endif + for(auto& geom : sceneGeoms) { + geom->draw(m_contextHandlerID, + Reveal::RENDERPROG, + m_uniforms[Reveal::RENDERPROG], + m_visibilityMask); + } + + //POST PROCESSING + if(m_postFilter>0) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, m_width, m_height); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glDisable(GL_BLEND); + glClearColor(0.0, 0.0, 0.0, !m_transparentBackground); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glUseProgram(m_programs[Reveal::POSTPROG]); + glActiveTexture(GL_TEXTURE0); + glUniform1i(m_uniforms[Reveal::POSTPROG][Reveal::RENDERTEX], 0); + glBindTexture(GL_TEXTURE_2D, m_renderTex); + glUniform1f(m_uniforms[Reveal::POSTPROG][Reveal::VIEWPORTWIDTH], + m_width); + glUniform1f(m_uniforms[Reveal::POSTPROG][Reveal::VIEWPORTHEIGHT], + m_height); + glUniform1f(m_uniforms[Reveal::POSTPROG][Reveal::POSTFILTER], + m_postFilter); + m_calibGeom->drawDirect(m_contextHandlerID); + } + + //SWAP + glfwSwapInterval(0); + glfwSwapBuffers(m_projWindow); + + //PROCESS OUTPUT +#ifdef GL42 + if(m_processOutput) { + processOutput(); + } +#endif +} + +void ProjectorModule::initGL() { + #ifdef OSX + glewExperimental = GL_TRUE; + #endif + glewInit(); + + + //POSTPROCESSING + { + const char * vertSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + " \n" + "in vec3 vertex; \n" + " \n" + "void main(void) {\n" + " gl_Position = vec4(vertex, 1.0);\n" + "}\n"}; + + const char * fragSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + " \n" + "uniform float viewportWidth;\n" + "uniform float viewportHeight;\n" + "uniform float postFilter;\n" +#ifdef GL42 + "layout(binding=0) uniform sampler2D renderTex;\n" +#else + "uniform sampler2D renderTex;\n" +#endif + " \n" + "out vec4 color;\n" + " \n" + "void main(void) {\n" + " float coordX = gl_FragCoord.x;\n" + " float coordY = gl_FragCoord.y;\n" + " ivec2 patSize = textureSize(renderTex, 0);\n" + " vec3 sumCol = vec3(0,0,0);\n" + " float cnt=0;\n" + " for(float dX = coordX-postFilter; dX <= coordX+postFilter; ++dX) {\n" + " for(float dY = coordY-postFilter; dY <= coordY+postFilter; ++dY) {\n" + " if(dX>=0 && dX<viewportWidth \n" + " && dY>=0 && dY<viewportHeight) {\n" + " sumCol+=texelFetch(renderTex, \n" + " ivec2((dX-0.5)/viewportWidth*patSize.x,\n" + " (dY-0.5)/viewportHeight*patSize.y),\n" + " 0).xyz; \n" + " cnt+=1;\n" + " }\n" + " }\n" + " }\n" + " color=vec4(sumCol.xyz/cnt, 1.0);\n" + "}\n"}; + m_programs[Reveal::POSTPROG] + = Reveal::getInstance()->createProgram(vertSource, fragSource); + m_uniforms[Reveal::POSTPROG]=map<Reveal::REVIL_UNIFORM, GLint>(); + m_uniforms[Reveal::POSTPROG][Reveal::VIEWPORTWIDTH] + = glGetUniformLocation(m_programs[Reveal::POSTPROG],"viewportWidth"); + m_uniforms[Reveal::POSTPROG][Reveal::VIEWPORTHEIGHT] + = glGetUniformLocation(m_programs[Reveal::POSTPROG],"viewportHeight"); + m_uniforms[Reveal::POSTPROG][Reveal::POSTFILTER] + = glGetUniformLocation(m_programs[Reveal::POSTPROG],"postFilter"); + m_uniforms[Reveal::POSTPROG][Reveal::RENDERTEX] + = glGetUniformLocation(m_programs[Reveal::POSTPROG],"renderTex"); + } + + + + //RENDER + { + const char * vertSource = { + #ifdef GL42 + "#version 430 \n" + #else + "#version 410 \n" + #endif + " \n" + "in vec3 vertex; \n" + "in vec2 texCoords;\n" + " \n" + "uniform mat4 modelMat;\n" + "uniform mat4 viewMat;\n" + "uniform mat4 viewProjMat;\n" + "uniform float mirrored;\n" + " \n" + "out vec3 viewRay;\n" + "out vec2 uvCoords;\n" + " \n" + "void main(void) {\n" + " vec4 posWS = modelMat * vec4(vertex, 1.0);\n" + " if(mirrored<1) {\n" + " posWS.x = -posWS.x;\n" + " }\n" + " gl_Position = viewProjMat * posWS;\n" + " viewRay = posWS.xyz - vec3(viewMat[3][0],\n" + " viewMat[3][1],\n" + " viewMat[3][2]);\n" + " uvCoords=texCoords;\n" + "}\n"}; + + const char * fragSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + "\n"//defined in Reveal.hpp + "const int BOX=0;\n" + "const int SPHERE=1;\n" + "const int TUBE=2;\n" + "const int CONE=3;\n" + "const int FRAME=4;\n" + "const int PATH=5;\n" + "const int MODEL=10;\n" + "\n" + "in vec3 viewRay;\n" + "in vec2 uvCoords;\n" + " \n" +#ifdef GL42 + "layout(binding=0) uniform sampler2D sliceTex;\n" + "layout(binding=1) uniform sampler2D selectTex;\n" + "layout(binding=2) uniform sampler3D insideTex;\n" + "layout(binding=3) uniform sampler2D surfaceTex;\n" + "layout(binding=4) uniform sampler3D reactTex;\n" + "layout(binding=5) uniform sampler3D surfDistTex;\n" + "layout(binding=6) uniform sampler2D gradientTex;\n" + "layout(r32ui, binding=7) uniform coherent uimage2D outputTex;\n" +#else + "uniform sampler2D sliceTex;\n" + "uniform sampler2D selectTex;\n" + "uniform sampler3D insideTex;\n" + "uniform sampler2D surfaceTex;\n" + "uniform sampler3D reactTex;\n" + "uniform sampler3D surfDistTex;\n" + "uniform sampler2D gradientTex;\n" +#endif + "uniform float viewportWidth;\n" + "uniform float viewportHeight;\n" + "uniform float mirrored;\n" + "uniform float shapeID;\n" + "uniform float shapeIDBit;\n" + "uniform int shapeGeom;\n" + "uniform float subShapeID;\n" + "uniform float subShapesNb;\n" + "uniform mat4 subShapeInvMat;\n" + "uniform mat4 viewMat;\n" + "uniform mat4 modelMat;\n" + "uniform mat4 invModelMat;\n" + "uniform vec3 modelScale;\n" + "uniform int revealedBy;\n" + "\n" + "uniform vec3 shapeColor;\n" + //0: none, 1:color, 2:texture + "uniform int surface;\n" + "uniform vec3 surfaceColor;\n" + "uniform int insideOutputOnly;\n" + "uniform int reactivity;\n" + "uniform float thickness;\n" + "\n" + "uniform int insideVisible;\n" + //0:from center, 1:along x, 2: along y, 3:along z, 4 :from surface + "uniform int insideStructure;\n" + "uniform float structureRatio;\n" + "\n" + "uniform float gradientAlpha;\n" + //0:greyscale, 1:texture + "uniform int gradientType;\n" + "uniform int gradientSteps;\n" + "uniform float gradientCurveRatio;\n" + "\n" + "uniform float densityAlpha;\n" + //0:layers, 1:grid, 2:pointcloud + "uniform int densityType;\n" + "uniform float densityRatio;\n" + "uniform float densitySize;\n" + "uniform float densityCurveRatio;\n" + "\n" + "uniform float texAlpha;\n" + "uniform vec3 texOffset;\n" + "uniform vec3 texScale;\n" + "uniform int texGray;\n" +#ifdef GL42 + "uniform int revSize;\n" + "uniform int revSurface;\n" + "uniform int revInside;\n" + "uniform int revCenter;\n" + "uniform int revCursor;\n" + "uniform int revColor;\n" + "uniform int revHisto;\n" + "uniform int revVoxels;\n" + "uniform float revSubShapeID;\n" + "uniform int shapeOutSize;\n" + "uniform int histoOutSize;\n" + "uniform int voxelOutSize;\n" + "uniform int depthOutSize;\n" + "uniform int depthOutNb;\n" + "uniform vec4 boundingRect;\n" +#endif + " \n" + "vec3 rgb2hsv(vec3 c) {\n" + " vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n" + " vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));\n" + " vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n" + " float d = q.x - min(q.w, q.y);\n" + " float e = 1.0e-10;\n" + " return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)),d/(q.x + e), q.x);\n" + "}\n" + + "float random (vec3 st) {\n" + " return fract(sin(dot(st.xyz,\n" + " vec3(12.9898,78.233, 102.234)))*\n" + " 43758.5453123);\n" + "}\n" + + "out vec4 color;\n" + " \n" + "void main(void) {\n" + //get fragment coordinates + " float coordX = (gl_FragCoord.x-0.5)/viewportWidth;\n" + " float coordY = (gl_FragCoord.y-0.5)/viewportHeight;\n" + " ivec2 sliSize = textureSize(sliceTex, 0);\n" + //retrieve pixel in slicing texture + " vec4 sli = texelFetch(sliceTex,\n" + " ivec2(coordX*float(sliSize.x), \n" + " coordY*float(sliSize.y)), \n" + " 0);\n" + " float pixZ=abs(gl_FragCoord.z);\n" + " float cutZ=abs(sli.z);\n" + " int depthID=int(sli.y)-1;\n" +#ifdef GL42 + " int outCols=imageSize(outputTex).x;\n" + " int outOffset=(int(shapeID-1)*depthOutNb+(depthID-1))*revSize;\n" +#endif + " int rendered=0;\n" + " vec3 finalColor = shapeColor;\n" + " float alpha=0;\n" + " vec3 pixelPosW;\n" + " vec3 pixelPos = vec3(0.0, 0.0, 1.0);\n" + " vec3 ratioWithinBox = vec3(0.0, 0.0, 0.0);\n" + " vec3 outRatioWithinBox = vec3(0.0, 0.0, 0.0);\n" + //if there is a slicing pixel aligned with our coordinate + //and we are revealed by this depth module + " if(cutZ>0 && (revealedBy & (1<<(1+depthID)))>0 ) { \n" + //compute the slicing pixel world position + " pixelPosW = vec3(viewMat[3][0], \n" + " viewMat[3][1], \n" + " viewMat[3][2])\n" + " + vec3(normalize(viewRay) * sli.w);\n" + " pixelPosW.x = pixelPosW.x*(-2.0*(1-mirrored)+1.0);\n" + //compute the slicing pixel position in model coords + " pixelPos = (invModelMat * vec4(pixelPosW,1.0)).xyz;\n" + "\n" + //depending on type, test if slicing pixel inside + //and retrieve distance to the surface on each axis + " vec3 diffMin = vec3(1.0);\n" + " vec3 diffMax = vec3(1.0);\n" + " switch(shapeGeom) {\n" + " case PATH : {\n"//use min/max/size of current segment + " pixelPos = (subShapeInvMat*vec4(pixelPos,1.0)).xyz;\n" + " if(length(vec2(pixelPos.x, pixelPos.y))<=0.5\n" + " && (pixelPos.z>-0.5 && pixelPos.z<0.5)) { \n" + " float xx = (pixelPos.x)*(pixelPos.x);\n" + " float yy = (pixelPos.y)*(pixelPos.y);\n" + " float ax = sqrt(0.25-yy);\n" + " diffMin.x = pixelPos.x+ax;\n" + " diffMax.x = ax-pixelPos.x;\n" + " float ay = sqrt(0.25-xx);\n" + " diffMin.y = pixelPos.y+ay;\n" + " diffMax.y = ay-pixelPos.y;\n" + " diffMin.z = pixelPos.z+0.5;\n" + " diffMax.z = 0.5-pixelPos.z;\n" + " rendered=1;\n" + " }\n" + " }break;\n" + " case CONE : {\n" + " if(pixelPos.y<0.5 && pixelPos.y>-0.5) {\n" + " float xx = (pixelPos.x)*(pixelPos.x);\n" + " float yy = (pixelPos.y-0.5)*(pixelPos.y-0.5);\n" + " float zz = (pixelPos.z)*(pixelPos.z);\n" + " if((xx+zz)/yy<0.25){ \n" + " float ax = sqrt(0.25*yy-zz);\n" + " diffMin.x = pixelPos.x+ax;\n" + " diffMax.x = ax-pixelPos.x;\n" + " float ay = sqrt((yy+xx)/0.25);\n" + " diffMin.y = pixelPos.y+0.5;\n" + " diffMax.y = 0.5-pixelPos.y;\n" + " float az = sqrt(0.25*yy-xx);\n" + " diffMin.z = pixelPos.z+az;\n" + " diffMax.z = az-pixelPos.z;\n" + " rendered=1;\n" + " }\n" + " }\n" + " } break;\n" + " case TUBE : {\n" + " if(length(vec2(pixelPos.x, pixelPos.z))<=0.5\n" + " && (pixelPos.y>-0.5 && pixelPos.y<0.5)) { \n" + " float xx = (pixelPos.x)*(pixelPos.x);\n" + " float zz = (pixelPos.z)*(pixelPos.z);\n" + " float ax = sqrt(0.25-zz);\n" + " diffMin.x = pixelPos.x+ax;\n" + " diffMax.x = ax-pixelPos.x;\n" + " float az = sqrt(0.25-xx);\n" + " diffMin.z = pixelPos.z+az;\n" + " diffMax.z = az-pixelPos.z;\n" + " diffMin.y = pixelPos.y+0.5;\n" + " diffMax.y = 0.5-pixelPos.y;\n" + " rendered=1;\n" + " }\n" + " } break;\n" + " case SPHERE : {\n" + " if(length(pixelPos)<=0.5) { \n" + " float xx = (pixelPos.x)*(pixelPos.x);\n" + " float yy = (pixelPos.y)*(pixelPos.y);\n" + " float zz = (pixelPos.z)*(pixelPos.z);\n" + " float ax = sqrt(0.25-yy-zz);\n" + " diffMin.x = pixelPos.x+ax;\n" + " diffMax.x = ax-pixelPos.x;\n" + " float ay = sqrt(0.25-xx-zz);\n" + " diffMin.y = pixelPos.y+ay;\n" + " diffMax.y = ay-pixelPos.y;\n" + " float az = sqrt(0.25-xx-yy);\n" + " diffMin.z = pixelPos.z+az;\n" + " diffMax.z = az-pixelPos.z;\n" + " rendered=1;\n" + " }\n" + " } break;\n" + " case BOX : {\n" + " diffMin = pixelPos - vec3(-0.5, -0.5, -0.5);\n" + " diffMax = vec3(0.5, 0.5, 0.5) - pixelPos;\n" + " if(diffMin.x>0 && diffMax.x>0\n" + " && diffMin.y>0 && diffMax.y>0\n" + " && diffMin.z>0 && diffMax.z>0){\n" + " rendered=1;\n" + " } \n" + " } break;\n" + " case FRAME : {\n" + " diffMin = pixelPos - vec3(-0.5, -0.5, -0.5);\n" + " diffMax = vec3(0.5, 0.5, 0.5) - pixelPos;\n" + " if(diffMin.x>0 && diffMax.x>0\n" + " && diffMin.y>0 && diffMax.y>0\n" + " && diffMin.z>0 && diffMax.z>0){\n" + " rendered=1;\n" + " } \n" + " } break;\n" + " case MODEL : {\n" + " ivec2 selSize = textureSize(selectTex, 0);\n" + " vec4 sel = texelFetch(selectTex,\n" + " ivec2(coordX*float(selSize.x), \n" + " coordY*float(selSize.y)), \n" + " 0);\n" + //get front surfaces before depth map + " if(pixZ<=cutZ+thickness/1000.0) { \n" + " if(sel.z==0) {\n" + " if(sel.x==shapeID) {\n" + " rendered=1;\n" + " }\n" + " else if((int(shapeIDBit)&int(sel.w))>0) {\n" + " diffMin = pixelPos - vec3(-0.5, -0.5, -0.5);\n" + " diffMax = vec3(0.5, 0.5, 0.5) - pixelPos;\n" + " if(diffMin.x>0 && diffMax.x>0\n" + " && diffMin.y>0 && diffMax.y>0\n" + " && diffMin.z>0 && diffMax.z>0){\n" + " rendered=1;\n" + " }\n" + " }\n" + " }\n" + " if(surface>0 \n" + " && (pixZ>cutZ \n" + " || (sel.z>0 && (int(shapeIDBit)&int(sel.w))>0))) {\n" + " rendered=2;\n" + " }\n" + " }\n" + " } break;\n" + " }\n" + " if(rendered>0) {\n" + " ratioWithinBox = (pixelPos)+0.5;\n" + //test if on the surface + " if(diffMin.x*modelScale.x<thickness || \n" + " diffMax.x*modelScale.x<thickness || \n" + " diffMin.y*modelScale.y<thickness || \n" + " diffMax.y*modelScale.y<thickness || \n" + " diffMin.z*modelScale.z<thickness || \n" + " diffMax.z*modelScale.z<thickness) { \n" + " rendered=2;\n" + " } \n" + //extend ratiowithinbox to multiplesubshapes + //and get gradient ratio according to type + " float gradRatio = 0;\n" + " vec3 subAdd;\n" + " vec3 subDiv;\n" + " if(insideStructure==0) {\n"//from center + " subAdd = vec3(subShapeID, subShapeID, subShapeID);\n" + " subDiv = vec3(subShapesNb, subShapesNb, subShapesNb);\n" + " ratioWithinBox.xyz=(ratioWithinBox.xyz+subAdd)/subDiv;\n" + " outRatioWithinBox.xyz=ratioWithinBox.xyz;\n" + " gradRatio = length(ratioWithinBox.xyz\n" + " - vec3(0.5,0.5,0.5))/0.5;\n" + " }\n" + " else {\n"//from surface or along axes + " subAdd = vec3(0,0, subShapeID);\n" + " subDiv = vec3(1,1, subShapesNb);\n" + " ratioWithinBox.xyz=(ratioWithinBox.xyz+subAdd)/subDiv;\n" + " outRatioWithinBox.xyz=ratioWithinBox.xyz;\n" + " if(insideStructure==1) {\n" + " ratioWithinBox.x=0.5;\n" + " }\n" + " else if(insideStructure==2) {\n" + " ratioWithinBox.y=0.5;\n" + " }\n" + " else if(insideStructure==3 && shapeGeom!=PATH) {\n" + " ratioWithinBox.z=0.5;\n" + " }\n" + " switch(shapeGeom) {\n" + " case BOX : {\n" + " vec3 q = abs(ratioWithinBox.xyz\n" + " -vec3(0.5,0.5,0.5))*2.0\n" + " - vec3(1.0,1.0,1.0);\n" + " gradRatio = 1.0-abs(length(max(q,0.0)) \n" + " + min(max(q.x,max(q.y,q.z)),0.0));\n" + " } break;\n" + " case SPHERE : {\n" + " gradRatio = length(ratioWithinBox.xyz\n" + " - vec3(0.5,0.5,0.5))/0.5;\n" + " } break;\n" + " case PATH : {\n" + " vec2 d = abs(vec2(length((ratioWithinBox.xy-vec2(0.5, 0.5))*2.0), \n" + " (ratioWithinBox.z-0.5)*2.0)) \n" + " - vec2(1.0,1.0);\n" + " gradRatio = 1.0 - abs(min(max(d.x,d.y),0.0)\n" + " + length(max(d,0.0)));\n" + " } break;\n" + " case TUBE : {\n" + " vec2 d = abs(vec2(length((ratioWithinBox.xz-vec2(0.5, 0.5))*2.0), \n" + " (ratioWithinBox.y-0.5)*2.0)) \n" + " - vec2(1.0,1.0);\n" + " gradRatio = 1.0 - abs(min(max(d.x,d.y),0.0)\n" + " + length(max(d,0.0)));\n" + " } break;\n" + " case CONE : {\n" + " float q = length((ratioWithinBox.xz\n" + " - vec2(0.5,0.5))*2.0);\n" + " gradRatio = 1.0-abs(max(dot(vec2(0.5,0.5),\n" + " vec2(q,(ratioWithinBox.y-1.0))),\n" + " -1.0-(ratioWithinBox.y-1.0)));\n" + " } break;\n" + " case FRAME : {\n" //FIXME compute frame SDF + " vec3 q = abs(ratioWithinBox.xyz\n" + " -vec3(0.5,0.5,0.5))*2.0\n" + " - vec3(1.0,1.0,1.0);\n" + " gradRatio = 1.0-abs(length(max(q,0.0)) \n" + " + min(max(q.x,max(q.y,q.z)),0.0));\n" + " } break;\n" + " case MODEL : {\n" + " gradRatio = texture(surfDistTex, \n" + " ratioWithinBox).r\n" + " * structureRatio;\n" + " } break;\n" + " default :{\n"//defaults to sphere + " gradRatio = length(ratioWithinBox.xyz\n" + " - vec3(0.5,0.5,0.5))/0.5;\n" + " } break;\n" + " }\n" + " }\n" + //texture coordinates + " vec3 texCoords = vec3(1-ratioWithinBox.x,\n" + " 1-ratioWithinBox.y,\n" + " ratioWithinBox.z);\n" + "\n" + //start with shapeColor + " finalColor = shapeColor;\n" + //test gradient + " if(gradientAlpha>0) {\n" + " float gradColor = \n" + " pow(gradientCurveRatio<0?1.0-gradRatio:gradRatio,\n" + " abs(gradientCurveRatio));\n" + " if(gradientSteps>1) {\n" + " gradColor = floor(gradColor*gradientSteps)\n" + " / gradientSteps;\n" + " }\n" + " gradColor*=(gradRatio<=1.0)?1.0:0.0;\n" + " if(gradientType>0) {\n"//gradient texture + " finalColor=finalColor*(1.0-gradientAlpha) \n" + " + finalColor*gradientAlpha\n" + " * texture(gradientTex, \n" + " vec2(gradRatio, 0.0)).xyz;\n" + " }\n" + " else {\n" + " finalColor=finalColor*(1.0-gradientAlpha) \n" + " + finalColor*gradColor*gradientAlpha;\n" + " }\n" + " }\n" + //test density + " if(densityAlpha>0) {\n" + " float densColor = \n" + " pow(densityCurveRatio<0?1.0-gradRatio:gradRatio,\n" + " abs(densityCurveRatio));\n" + " if(densityType==0 && \n" //layers + " length(mod(densColor*100.0, \n" + " densitySize*100.0))\n" + " < densityRatio*densitySize*100.0) {\n" + " densColor = 1.0;\n" + " densColor*=(gradRatio<=1.0)?1.0:0.0;\n" + " }\n" + " else if(densityType==1\n" //grid + " && (length(mod(ratioWithinBox.x*100,\n" + " densitySize*100.0))\n" + " <densitySize*densityRatio*100.0 \n" + " || length(mod(ratioWithinBox.y*100,\n" + " densitySize*100.0))\n" + " <densitySize*densityRatio*100.0 \n" + " || length(mod(ratioWithinBox.z*100,\n" + " densitySize*100.0))\n" + " <densitySize*densityRatio*100.0)) { \n" + " densColor = 1.0;\n" + " }\n" + " else if(densityType==2 \n" //pointcloud + " && floor(random(ratioWithinBox.xyz)\n" + " *floor(100.0))>100.0*densColor) {\n" + " densColor = 1.0; \n" + " densColor*=(gradRatio<=1.0)?1.0:0.0;\n" + " }\n" + " else {\n" + " densColor = 0.0;\n" + " }\n" + " finalColor=finalColor*(1.0-densityAlpha) \n" + " + finalColor*densColor*densityAlpha;\n" + " }\n" + //test texture + " if(texAlpha>0) {\n" + " vec3 texColor = texture(insideTex, \n" + " texOffset+texScale*texCoords).xyz;\n" + " if(texGray>0) {\n" + " texColor=vec3((texColor.r+texColor.g+texColor.b)\n" + " / 3.0);\n" + " }\n" + " finalColor=finalColor*(1.0-texAlpha) \n" + " + finalColor*texColor*texAlpha;\n" + " }\n" +#ifdef GL42 + //if revealing something, output values + " if(sli.x>=1.0 && depthID<=depthOutNb) {\n" + //inside output + " if(revInside>0 && rendered==1) {\n" + " imageAtomicMax(outputTex, \n" + " ivec2(mod(outOffset+revInside,outCols), \n" + " floor((outOffset+revInside))/outCols),\n" + " 1);\n" + " }\n" + " outRatioWithinBox.x=clamp(outRatioWithinBox.x, 0, 1);\n" + " outRatioWithinBox.y=clamp(outRatioWithinBox.y, 0, 1);\n" + " outRatioWithinBox.z=clamp(outRatioWithinBox.z, 0, 1);\n" + //compute min,max on the three axes + " int xk=int(outRatioWithinBox.x*1000.0);\n" + " int yk=int(outRatioWithinBox.y*1000.0);\n" + " int zk=int(outRatioWithinBox.z*1000.0);\n" + //output min/max ratios + " if(revCenter>0) {\n" + " imageAtomicMax(outputTex, \n" + " ivec2(mod(outOffset+revCenter+0,outCols), \n" + " floor((outOffset+revCenter+0)/outCols)),\n" + " 1000-xk);\n" + " imageAtomicMax(outputTex, \n" + " ivec2(mod(outOffset+revCenter+1,outCols), \n" + " floor((outOffset+revCenter+1)/outCols)),\n" + " xk);\n" + " imageAtomicMax(outputTex, \n" + " ivec2(mod(outOffset+revCenter+2,outCols), \n" + " floor((outOffset+revCenter+2)/outCols)),\n" + " 1000-yk);\n" + " imageAtomicMax(outputTex, \n" + " ivec2(mod(outOffset+revCenter+3,outCols), \n" + " floor((outOffset+revCenter+3)/outCols)),\n" + " yk);\n" + " imageAtomicMax(outputTex, \n" + " ivec2(mod(outOffset+revCenter+4,outCols), \n" + " floor((outOffset+revCenter+4)/outCols)),\n" + " 1000-zk);\n" + " imageAtomicMax(outputTex, \n" + " ivec2(mod(outOffset+revCenter+5,outCols), \n" + " floor((outOffset+revCenter+5)/outCols)),\n" + " zk);\n" + " }\n" + //convert from rgb to hsv + " vec3 hsv = rgb2hsv(finalColor);\n" + //Sum color channels + " if(revColor>0) {\n" + //count nb revealed points + " imageAtomicAdd(outputTex,\n" + " ivec2(mod(outOffset+revColor+0,outCols), \n" + " floor((outOffset+revColor+0)/outCols)),\n" + " 1);\n" + //sum point h + " imageAtomicAdd(outputTex,\n" + " ivec2(mod(outOffset+revColor+1,outCols), \n" + " floor((outOffset+revColor+1)/outCols)),\n" + " clamp(int(hsv.x*1000.0),0,1000));\n" + //sum s + " imageAtomicAdd(outputTex,\n" + " ivec2(mod(outOffset+revColor+2,outCols), \n" + " floor((outOffset+revColor+2)/outCols)),\n" + " clamp(int(hsv.y*1000.0),0,1000));\n" + //sum v + " imageAtomicAdd(outputTex,\n" + " ivec2(mod(outOffset+revColor+3,outCols), \n" + " floor((outOffset+revColor+3)/outCols)),\n" + " clamp(int(hsv.z*1000.0),0,1000));\n" + " }\n" + //histo : accumulate on luminance bins + " if(revHisto>0) {\n" + //count nb revealed points + " imageAtomicAdd(outputTex,\n" + " ivec2(mod(outOffset+revHisto,outCols), \n" + " floor((outOffset+revHisto)/outCols)),\n" + " 1);\n" + " int bin = int(hsv.z*float(histoOutSize-1));\n" + " imageAtomicAdd(outputTex,\n" + " ivec2(mod(outOffset+revHisto+1+bin,outCols), \n" + " floor((outOffset+revHisto+1+bin)/outCols)),\n" + " 1);\n" + " }\n" + + //2D grid of projected voxels (nbvox, 3D coords, lum) + " if(revVoxels>0) {\n" + //compute pixel ratio within 2D bounding rect + " vec2 pixRatio = (vec2(coordX, coordY)\n" + " - boundingRect.xy) / \n" + " (boundingRect.zw-boundingRect.xy);\n" + " pixRatio.x = clamp(pixRatio.x, 0.0, 1.0);\n" + " pixRatio.y = clamp(pixRatio.y, 0.0, 1.0);\n" + //compute offset in voxel output + " int voxOff = outOffset+revVoxels;\n" + " voxOff+=5*(int(pixRatio.x*voxelOutSize)\n" + " + int((1.0-pixRatio.y)*voxelOutSize)\n" + " *voxelOutSize);\n" + //accumulate points + " imageAtomicAdd(outputTex,\n" + " ivec2(mod(voxOff,outCols), \n" + " floor((voxOff)/outCols)),\n" + " 1);\n" + //accumulate coords + " imageAtomicAdd(outputTex, \n" + " ivec2(mod(voxOff+1,outCols), \n" + " floor((voxOff+1)/outCols)),\n" + " clamp(int(outRatioWithinBox.x*1000.0),0,1000));\n" + " imageAtomicAdd(outputTex, \n" + " ivec2(mod(voxOff+2,outCols), \n" + " floor((voxOff+2)/outCols)),\n" + " clamp(int(outRatioWithinBox.y*1000.0),0,1000));\n" + " imageAtomicAdd(outputTex, \n" + " ivec2(mod(voxOff+3,outCols), \n" + " floor((voxOff+3)/outCols)),\n" + " clamp(int(outRatioWithinBox.z*1000.0),0,1000));\n" + //accumulate lum + " imageAtomicAdd(outputTex, \n" + " ivec2(mod(voxOff+4,outCols), \n" + " floor((voxOff+4)/outCols)),\n" + " clamp(int(hsv.z*1000.0),0,1000));\n" + " }\n" + " }\n" +#endif + " }\n" + //SURFACE test + " if(rendered>1) { \n" + " finalColor = surfaceColor;\n" +#ifdef GL42 + " if(revSurface>0 && sli.x>=1.0 && depthID<=depthOutNb) {\n" + " imageAtomicMax(outputTex,\n" + " ivec2(mod(outOffset+revSurface,outCols), \n" + " floor((outOffset+revSurface)/outCols)),\n" + " 1);\n" + " }\n" +#endif + " }\n" + " }\n" + //final test, output if rendered or not, output final color + " if(rendered>0 && length(finalColor)>0) { \n" +#ifdef GL42 + " if(revSize>0) {\n" + " imageAtomicOr(outputTex, \n" + " ivec2(mod(outOffset,outCols), \n" + " floor((outOffset))/outCols),\n" + " rendered);\n" + " }\n" +#endif + " if((insideVisible>0 && rendered==1) \n" + " || (surface>0 && rendered==2)) {\n" + " color = vec4(finalColor, 1.0);\n"//display + //" color = vec4(finalColor, sli.x);\n"//display + /* + " if(sli.x>0.5) {\n" + " color = vec4(1.0, 0.0, 0.0, 1.0);\n"//display + " }\n" + " else {\n" + " color = vec4(0.0, 1.0, 0.0, 1.0);\n"//display + " }\n" + */ + " }\n" + " else {\n" + " color = vec4(0.0, 0.0, 0.0, 1.0);\n" + " }\n" + //" color = vec4((pixelPos+0.5)/2.0, 1.0);\n"//debug pix coords + //" color = vec4(cutZ*10.0, pixZ*10.0, 0.0, 1.0);\n"//debug slice texture + //" color = vec4(texture(surfDistTex, ratioWithinBox).r*10.0, 1.0,1.0,1.0);\n" + //" color = vec4(texture(insideTex, ratioWithinBox).r*10.0, 1.0,1.0,1.0);\n" + //" color = vec4(ratioWithinBox.xyz, 1.0);\n" + " }\n" + " else {\n" //DISCARD + //" color = vec4(1.0,0.0,0.0,1.0);\n" + " discard;\n" + " }\n" + "}\n"}; + m_programs[Reveal::RENDERPROG] + = Reveal::getInstance()->createProgram(vertSource, fragSource); + m_uniforms[Reveal::RENDERPROG] = map<Reveal::REVIL_UNIFORM, GLint>(); + m_uniforms[Reveal::RENDERPROG][Reveal::MIRRORED] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "mirrored"); + m_uniforms[Reveal::RENDERPROG][Reveal::VIEWPROJMAT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "viewProjMat"); + m_uniforms[Reveal::RENDERPROG][Reveal::VIEWMAT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "viewMat"); + m_uniforms[Reveal::RENDERPROG][Reveal::MODELMAT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "modelMat"); + m_uniforms[Reveal::RENDERPROG][Reveal::INVMODELMAT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "invModelMat"); + m_uniforms[Reveal::RENDERPROG][Reveal::MODELSCALE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "modelScale"); + m_uniforms[Reveal::RENDERPROG][Reveal::VIEWPORTWIDTH] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "viewportWidth"); + m_uniforms[Reveal::RENDERPROG][Reveal::VIEWPORTHEIGHT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG],"viewportHeight"); + m_uniforms[Reveal::RENDERPROG][Reveal::SLICETEX] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "sliceTex"); + m_uniforms[Reveal::RENDERPROG][Reveal::SELECTTEX] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "selectTex"); + m_uniforms[Reveal::RENDERPROG][Reveal::INSIDETEX] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "insideTex"); + m_uniforms[Reveal::RENDERPROG][Reveal::COORDSTEX] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "coordsTex"); + m_uniforms[Reveal::RENDERPROG][Reveal::TEXGRAY] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "texGray"); + m_uniforms[Reveal::RENDERPROG][Reveal::REACTTEX] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "reactTex"); + m_uniforms[Reveal::RENDERPROG][Reveal::SURFDISTEX] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "surfDistTex"); + + m_uniforms[Reveal::RENDERPROG][Reveal::SHAPEID] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "shapeID"); + m_uniforms[Reveal::RENDERPROG][Reveal::SHAPEIDBIT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "shapeIDBit"); + m_uniforms[Reveal::RENDERPROG][Reveal::SHAPEGEOM] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "shapeGeom"); + m_uniforms[Reveal::RENDERPROG][Reveal::SHAPECOLOR] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "shapeColor"); + m_uniforms[Reveal::RENDERPROG][Reveal::SUBSHAPEID] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "subShapeID"); + m_uniforms[Reveal::RENDERPROG][Reveal::SUBSHAPESNB] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "subShapesNb"); + m_uniforms[Reveal::RENDERPROG][Reveal::SUBSHAPEINVMAT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG],"subShapeInvMat"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVEALEDBY] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revealedBy"); + + m_uniforms[Reveal::RENDERPROG][Reveal::SURFACE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "surface"); + m_uniforms[Reveal::RENDERPROG][Reveal::SURFACECOLOR] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "surfaceColor"); + m_uniforms[Reveal::RENDERPROG][Reveal::SURFACETHICKNESS] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "thickness"); + m_uniforms[Reveal::RENDERPROG][Reveal::SURFACETEX] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "surfaceTex"); + + m_uniforms[Reveal::RENDERPROG][Reveal::INSIDEVISIBLE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "insideVisible"); + m_uniforms[Reveal::RENDERPROG][Reveal::INSIDESTRUCT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "insideStructure"); + m_uniforms[Reveal::RENDERPROG][Reveal::STRUCTRATIO] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "structureRatio"); + + m_uniforms[Reveal::RENDERPROG][Reveal::GRADIENTALPHA] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "gradientAlpha"); + m_uniforms[Reveal::RENDERPROG][Reveal::GRADIENTTYPE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "gradientType"); + m_uniforms[Reveal::RENDERPROG][Reveal::GRADIENTSTEPS] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "gradientSteps"); + m_uniforms[Reveal::RENDERPROG][Reveal::GRADIENTCURVERATIO] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "gradientCurveRatio"); + m_uniforms[Reveal::RENDERPROG][Reveal::GRADIENTTEXTURE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "gradientTex"); + + m_uniforms[Reveal::RENDERPROG][Reveal::DENSITYALPHA] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "densityAlpha"); + m_uniforms[Reveal::RENDERPROG][Reveal::DENSITYTYPE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "densityType"); + m_uniforms[Reveal::RENDERPROG][Reveal::DENSITYRATIO] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "densityRatio"); + m_uniforms[Reveal::RENDERPROG][Reveal::DENSITYSIZE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "densitySize"); + m_uniforms[Reveal::RENDERPROG][Reveal::DENSITYCURVERATIO] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "densityCurveRatio"); + + m_uniforms[Reveal::RENDERPROG][Reveal::TEXALPHA] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "texAlpha"); + m_uniforms[Reveal::RENDERPROG][Reveal::TEXOFFSET] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "texOffset"); + m_uniforms[Reveal::RENDERPROG][Reveal::TEXSCALE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "texScale"); + m_uniforms[Reveal::RENDERPROG][Reveal::REACTIVITY] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "reactivity"); + + + m_uniforms[Reveal::RENDERPROG][Reveal::BBOXMIN] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "bboxMin"); + m_uniforms[Reveal::RENDERPROG][Reveal::BBOXSIZE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "bboxSize"); + m_uniforms[Reveal::RENDERPROG][Reveal::BBOXLOCALSIZE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "bboxLocalSize"); + m_uniforms[Reveal::RENDERPROG][Reveal::BBOXROT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "bboxRot"); +#ifdef GL42 + //output texture + m_outputImg = new unsigned int[m_outputImgSize*m_outputImgSize]; + m_outputImgInit = new unsigned int[m_outputImgSize*m_outputImgSize]; + memset(&m_outputImgInit[0], 0, m_outputImgSize*m_outputImgSize*4); + glGenTextures(1, &m_outputTex); + glBindTexture(GL_TEXTURE_2D, m_outputTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, + m_outputImgSize, m_outputImgSize, 0, + GL_RED_INTEGER, GL_UNSIGNED_INT, m_outputImgInit); + m_uniforms[Reveal::RENDERPROG][Reveal::OUTPUTTEX] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "outputTex"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVSIZE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revSize"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVSURFACE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revSurface"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVINSIDE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revInside"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVCENTER] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revCenter"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVCURSOR] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revCursor"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVCOLOR] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revColor"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVHISTO] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revHisto"); + m_uniforms[Reveal::RENDERPROG][Reveal::REVVOXELS] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "revVoxels"); + m_uniforms[Reveal::RENDERPROG][Reveal::OUTSHAPESIZE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "shapeOutSize"); + m_uniforms[Reveal::RENDERPROG][Reveal::OUTHISTOSIZE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "histoOutSize"); + m_uniforms[Reveal::RENDERPROG][Reveal::OUTVOXELSIZE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "voxelOutSize"); + m_uniforms[Reveal::RENDERPROG][Reveal::OUTDEPTHSIZE] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "depthOutSize"); + m_uniforms[Reveal::RENDERPROG][Reveal::OUTNBDEPTH] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "depthOutNb"); + m_uniforms[Reveal::RENDERPROG][Reveal::BRECT] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "boundingRect"); + createRTT(m_renderTex, m_renderFBO, m_rttWidth, m_rttHeight, false); +#endif + } + + { + //select prog + const char * vertSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + " \n" + "in vec3 vertex;\n" + " \n" + "uniform mat4 modelMat;\n" + "uniform mat4 viewMat;\n" + "uniform mat4 viewProjMat;\n" + "uniform float mirrored;\n" + " \n" + "void main(void) {\n" + " vec4 posWS = modelMat * vec4(vertex, 1.0);\n" + " if(mirrored<1) {\n" + " posWS.x = -posWS.x;\n" + " }\n" + " gl_Position = viewProjMat * posWS;\n" + "}\n"}; + + const char * fragSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + " \n" +#ifdef GL42 + "layout(binding=0) uniform sampler2D sliceTex;\n" +#else + "uniform sampler2D sliceTex;\n" +#endif + "uniform float viewportWidth;\n" + "uniform float viewportHeight;\n" + "uniform float shapeID;\n" + "uniform float shapeIDBit;\n" + "uniform float mirrored;\n" + "uniform float thickness;\n" + "uniform int surface;\n" + " \n" + "out vec4 color;\n" + " \n" + "void main(void) {\n" + " float coordX = (gl_FragCoord.x-0.5)/viewportWidth;\n" + " float coordY = (gl_FragCoord.y-0.5)/viewportHeight;\n" + " ivec2 sliSize = textureSize(sliceTex, 0);\n" + " vec4 sli = texelFetch(sliceTex,\n" + " ivec2(coordX*float(sliSize.x),\n" + " coordY*float(sliSize.y)),\n" + " 0);\n" + " float pixZ=abs(gl_FragCoord.z);\n" + " float cutZ=abs(sli.z);\n" + // keep all ids of back surfaces after depth map + " if(pixZ>cutZ && cutZ>0) {\n" + " if((mirrored<1 && !gl_FrontFacing)\n" + " || (mirrored>0 && gl_FrontFacing)) {\n" + " color = vec4(shapeID, 0, \n" + " (abs(pixZ-cutZ)<thickness/1000.0 && surface>0)?1:0, \n" + " shapeIDBit);\n" + " }\n" + " else {\n" //occlude back when front face also behind + " color = vec4(-shapeID, 0, 0, -shapeIDBit);\n" + " }\n" + " }\n" + " else {\n" + " discard;\n" + " }\n" + "}\n"}; + m_programs[Reveal::SELECTPROG] + = Reveal::getInstance()->createProgram(vertSource, fragSource); + m_uniforms[Reveal::SELECTPROG]=map<Reveal::REVIL_UNIFORM, GLint>(); + m_uniforms[Reveal::SELECTPROG][Reveal::MIRRORED] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "mirrored"); + m_uniforms[Reveal::SELECTPROG][Reveal::VIEWPROJMAT] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "viewProjMat"); + m_uniforms[Reveal::SELECTPROG][Reveal::VIEWMAT] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "viewMat"); + m_uniforms[Reveal::SELECTPROG][Reveal::MODELMAT] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "modelMat"); + m_uniforms[Reveal::SELECTPROG][Reveal::VIEWPORTWIDTH] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "viewportWidth"); + m_uniforms[Reveal::SELECTPROG][Reveal::VIEWPORTHEIGHT] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG],"viewportHeight"); + m_uniforms[Reveal::SELECTPROG][Reveal::SLICETEX] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "sliceTex"); + m_uniforms[Reveal::SELECTPROG][Reveal::SHAPEID] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "shapeID"); + m_uniforms[Reveal::SELECTPROG][Reveal::SHAPEIDBIT] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "shapeIDBit"); + m_uniforms[Reveal::SELECTPROG][Reveal::SURFACETHICKNESS] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "thickness"); + m_uniforms[Reveal::SELECTPROG][Reveal::SURFACE] + = glGetUniformLocation(m_programs[Reveal::SELECTPROG], "surface"); + createRTT(m_selectTex, m_selectFBO, m_rttWidth, m_rttHeight, false); + } + + //SLICE + { + const char * vertSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + " \n" + "#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b);\n" + "#define mn3(a, b, c) s2(a, b); s2(a, c);\n" + "#define mx3(a, b, c) s2(b, c); s2(a, c);\n" + "#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b);\n" + "#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d);\n" + "#define mnmx5(a, b, c, d, e) s2(a,b); s2(c,d);mn3(a,c,e);mx3(b,d,e);\n" + "#define mnmx6(a,b,c,d,e,f) s2(a,d);s2(b,e);s2(c,f);mn3(a,b,c);mx3(d,e,f);\n" + "in vec3 vertex; \n" + " \n" +#ifdef GL42 + "layout(binding=0) uniform sampler2D depthCamTex;\n" + "layout(binding=1) uniform sampler2D depthCamTexFil;\n" + "layout(binding=2) uniform sampler2D markersTex;\n" + //"layout(r32ui, binding=2) uniform coherent uimage2D outputTex;\n" +#else + "uniform sampler2D depthCamTex;\n" + "uniform sampler2D depthCamTexFil;\n" + "uniform sampler2D markersTex;\n" +#endif + "uniform mat4 modelMat;\n" + "uniform mat4 viewMat;\n" + "uniform mat4 viewProjMat;\n" + "uniform float camXReso;\n" + "uniform float camYReso;\n" + "uniform float camXZFactor;\n" + "uniform float camYZFactor;\n" + "uniform int camFilter;\n" + "uniform int background;\n" + "uniform float camContThresh;\n" + "uniform float camMarkers;\n" + "uniform int depthType;\n" + "uniform int depthID;\n" + "uniform float outputCurs;\n" + "uniform float mirrored;\n" + " \n" + "out vec3 viewRay;\n" + "out float kept;\n" + "flat out int outDepthID;\n" + " \n" + "void main(void) {\n" + " vec4 depthPos = vec4(0, 0, 0, 1);\n" + " vec4 posWS = vec4(0, 0, 0, 1);\n" + //depth camera + " if(depthType==0) {\n" + " vec2 coords = vertex.xy;\n" + //get marker if any + " if(camMarkers>0) {\n" + " outDepthID = int(float(texture(markersTex,\n" + " vec2(coords.x/camXReso,\n" + " coords.y/camYReso)).r)\n" + " * 255.0);\n" + " }\n" + " else {\n" + " outDepthID=depthID+1;\n" + " }\n" + //get depth pixel in camera texture + " float depth = \n" + " float(texture(depthCamTex,\n" + " vec2(coords.x/camXReso,\n" + " coords.y/camYReso)).r)\n" + " * 65535.0;\n" + " kept=1.0;\n" + " float backgroundDepth=0;\n" + " if(background>0) {\n" + " float backDepth = float(texture(depthCamTex,\n" + " vec2(coords.x/camXReso,\n" + " coords.y/camYReso)).r)\n" + " * 65535.0;\n" + " if(backDepth<depth) {\n" + " depth=backDepth;\n" + " backgroundDepth=1;\n" + " }\n" + " }\n" + " if(depth<=500.0 || depth>8000.0) {\n" + " kept=0.0;\n" + " }\n" + " else if(backgroundDepth==0) {\n" + //filter out contours + " float maxD=camContThresh;\n" + " bool contour=false;\n" + " for(int dX = -1; dX <= 1; ++dX) {\n" + " for(int dY = -1; dY <= 1; ++dY) {\n" + " if(abs(float(texture(depthCamTex,\n" + " vec2((coords.x+dX)/camXReso,\n" + " (coords.y+dY)/camYReso)).r)\n" + " * 65535.0\n" + " - depth) > maxD) {\n" + " contour=true;\n" + " }\n" + " }\n" + " }\n" + " if(contour) {\n" + " kept=0.0;\n" + " }\n" + //see if needs filtering + " if(camFilter>0) {\n" + " float filtDepth = float(texture(depthCamTexFil,\n" + " vec2(coords.x/camXReso,\n" + " coords.y/camYReso)).r)\n" + " * 65535.0;\n" + //select either filtered version or current one + //depending on movement + " if(abs(filtDepth-depth)<camContThresh) {\n" + " float filRatio = abs(filtDepth-depth)/camContThresh;\n" + " depth=(1-filRatio)*filtDepth+(filRatio)*depth;\n" + " }\n" + " }\n" + " }\n" + //test distance again + " if(depth<=500.0 || depth>8000.0) {\n" + " kept=0.0;\n" + " }\n" + //compute position in world units + " depthPos = vec4((vertex.x/camXReso-0.5)\n" + " *depth*camXZFactor,\n" + " (0.5-(vertex.y/camYReso))\n" + " *depth*camYZFactor,\n" + " depth,\n" + " 1.0);\n" + //get world pos + " posWS = modelMat * depthPos;\n" + " }\n" + //other slicing shapes + " else {\n" + " outDepthID=depthID+1;\n" + " kept=1.0;\n" + " depthPos=vec4(vertex, 1.0);\n" + " posWS = modelMat * depthPos;\n" + " if(mirrored<1) {\n" + " posWS.x = -posWS.x;\n" + " }\n" + " }\n" +#ifdef GL42 +/* + //output minimum point on z axis if output is active + " if(outputCurs>0 && kept>0.0) {\n" + " imageAtomicMin(outputTex,ivec2(0,int(depthID)+500),\n" + " int(floor(1000.0+posWS.z/10.0)*1000000\n" + " +floor(posWS.y/10.0+500.0)*1000\n" + " +floor(posWS.x/10.0+500.0)));\n" + //" imageAtomicMin(outputTex,ivec2(0, int(depthID)+500),4400600);\n" + //" imageAtomicMin(outputTex,ivec2(0, int(depthID)+500),6400600);\n" + " }\n" +*/ +#endif + //keep/interpolate ray from view to each vertex + " viewRay = (posWS.xyz - vec3(viewMat[3][0],\n" + " viewMat[3][1],\n" + " viewMat[3][2]));\n" + " gl_Position = viewProjMat * posWS;\n" + "}\n"}; + const char * fragSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + " \n" + "in float kept;\n" + "in vec3 viewRay;\n" + "flat in int outDepthID;\n" + " \n" + "out vec4 color;\n" + " \n" + "void main(void) {\n" + " float thresh=0.8;\n" + " if(kept>=thresh) {\n" + " color = vec4((kept-thresh)/(1.0-thresh),\n" + " float(outDepthID),\n" + " gl_FragCoord.z,\n" + " length(viewRay));\n" + " }\n" + " else {\n" + " discard;\n" + " }\n" +// " color = vec4(1.0, 1.0, 0.0, 1.0);\n" + "}\n"}; + + m_programs[Reveal::SLICEPROG] + = Reveal::getInstance()->createProgram(vertSource, fragSource); + m_uniforms[Reveal::SLICEPROG]=map<Reveal::REVIL_UNIFORM, GLint>(); + m_uniforms[Reveal::SLICEPROG][Reveal::BACKGROUND] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "background"); + m_uniforms[Reveal::SLICEPROG][Reveal::MIRRORED] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "mirrored"); + m_uniforms[Reveal::SLICEPROG][Reveal::VIEWPROJMAT] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "viewProjMat"); + m_uniforms[Reveal::SLICEPROG][Reveal::VIEWMAT] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "viewMat"); + m_uniforms[Reveal::SLICEPROG][Reveal::MODELMAT] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "modelMat"); + m_uniforms[Reveal::SLICEPROG][Reveal::DEPTHTYPE] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "depthType"); + m_uniforms[Reveal::SLICEPROG][Reveal::DEPTHID] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "depthID"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMXRESO] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "camXReso"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMYRESO] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "camYReso"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMXZFACTOR] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "camXZFactor"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMYZFACTOR] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "camYZFactor"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMTEX] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "depthCamTex"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMTEXFIL] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "depthCamTexFil"); + m_uniforms[Reveal::SLICEPROG][Reveal::MARKTEX] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "markersTex"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMFILTER] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "camFilter"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMCONTOURTHRESH] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "camContThresh"); + m_uniforms[Reveal::SLICEPROG][Reveal::CAMMARKERS] + = glGetUniformLocation(m_programs[Reveal::SLICEPROG], "camMarkers"); + createRTT(m_sliceRttTex, m_sliceFBO, m_rttWidth, m_rttHeight, false); + } + + //Calibration + { + const char * vertSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + " \n" + "in vec3 vertex; \n" + " \n" + "void main(void) {\n" + " gl_Position = vec4(vertex, 1.0);\n" + "}\n"}; + + const char * fragSource = { +#ifdef GL42 + "#version 430 \n" +#else + "#version 410 \n" +#endif + " \n" + "uniform float viewportWidth;\n" + "uniform float viewportHeight;\n" + "uniform float patW;\n" + "uniform float patPosX;\n" + "uniform float patPosY;\n" + "uniform float patNbX;\n" + "uniform float patNbY;\n" + "uniform float patBright;\n" + "uniform vec2 patOffset;\n" + "uniform vec2 patRange;\n" +#ifdef GL42 + "layout(binding=0) uniform sampler2D patternTex;\n" +#else + "uniform sampler2D patternTex;\n" +#endif + " \n" + "out vec4 color;\n" + " \n" + "void main(void) {\n" + /* + " float coordX = (gl_FragCoord.x-0.5)/viewportWidth;\n" + " float coordY = (gl_FragCoord.y-0.5)/viewportHeight;\n" + " ivec2 patSize = textureSize(patternTex, 0);\n" + " float pat = texelFetch(patternTex,\n" + " ivec2(coordX*float(patSize.x),\n" + " (1.0-coordY)*float(patSize.y)),\n" + " 0).r;\n" + " color=vec4(pat, pat, pat, 1.0);\n" + //" color=vec4(1.0,1.0,1.0,1.0);\n" + */ + //pixel is white by default + " color = vec4(patBright);\n" + " float offX = gl_FragCoord.x - patPosX;\n" + " float offY = (viewportHeight-gl_FragCoord.y) - patPosY;\n" + //black squares + " if(offX>=0 && offX<patW*(patNbX+1)\n" + " && offY>=0 && offY<patW*(patNbY+1)) {\n" + " if((mod(offX,patW*2)<patW && mod(offY,patW*2)<patW) \n" + " || (mod(offX,patW*2)>patW && mod(offY,patW*2)>patW)) {\n" + " color = vec4(0, 0, 0, 1);\n" + " }\n" + " }\n" + //color in red the pattern range border + " float thick=2;\n" + " float coordY = viewportHeight-gl_FragCoord.y;\n" + " if(((abs(gl_FragCoord.x-patOffset.x)<thick\n" + " || abs(gl_FragCoord.x-(patOffset.x+patRange.x))<thick)\n" + " && coordY>patOffset.y\n" + " && coordY<(patOffset.y+patRange.y))\n" + " ||((abs(coordY-patOffset.y)<thick\n" + " || abs(coordY-(patOffset.y+patRange.y))<thick)\n" + " && gl_FragCoord.x>patOffset.x\n" + " && gl_FragCoord.x<(patOffset.x+patRange.x))) {\n" + " color=vec4(1,0,0,1);\n" + " }\n" + "}\n"}; + m_programs[Reveal::CALIBPROG] + = Reveal::getInstance()->createProgram(vertSource, fragSource); + m_uniforms[Reveal::CALIBPROG]=map<Reveal::REVIL_UNIFORM, GLint>(); + m_uniforms[Reveal::CALIBPROG][Reveal::VIEWPORTWIDTH] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"viewportWidth"); + m_uniforms[Reveal::CALIBPROG][Reveal::VIEWPORTHEIGHT] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"viewportHeight"); + + /* + m_uniforms[Reveal::CALIBPROG][Reveal::PATTERNTEX] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patternTex"); + */ + + + m_uniforms[Reveal::CALIBPROG][Reveal::PATW] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patW"); + m_uniforms[Reveal::CALIBPROG][Reveal::PATPOSX] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patPosX"); + m_uniforms[Reveal::CALIBPROG][Reveal::PATPOSY] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patPosY"); + m_uniforms[Reveal::CALIBPROG][Reveal::PATNBX] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patNbX"); + m_uniforms[Reveal::CALIBPROG][Reveal::PATNBY] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patNbY"); + m_uniforms[Reveal::CALIBPROG][Reveal::PATRANGE] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patRange"); + m_uniforms[Reveal::CALIBPROG][Reveal::PATOFFSET] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patOffset"); + m_uniforms[Reveal::CALIBPROG][Reveal::PATBRIGHT] + = glGetUniformLocation(m_programs[Reveal::CALIBPROG],"patBright"); + + + m_calibGeom = new QuadGeometry(); + } +} + +void ProjectorModule::createRTT(GLuint& tex, GLuint& fbo, + const int& width, const int& height, + bool filter) { + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, + 0, GL_RGBA, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + filter?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + filter?GL_LINEAR:GL_NEAREST); + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0); + GLenum drawBuffers[1] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(1, drawBuffers); + GLuint idDepthrenderbuffer; + glGenRenderbuffers(1, &idDepthrenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, idDepthrenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, + width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, idDepthrenderbuffer); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void ProjectorModule::deleteModule() { + if(m_space) { + m_space->removeProj(this); + } + glfwDestroyWindow(m_projWindow); + Module::deleteModule(); +} + +void ProjectorModule::setSpace(SpaceModule* space) { + m_space=space; +} + +void ProjectorModule::refreshDepthCamList(const vector<DepthCamModule*> cams) { + vector<string> labels; + labels.push_back("none"); + vector<DepthCamModule*>::const_iterator itCam=cams.begin(); + for(; itCam!=cams.end(); ++itCam) { + labels.push_back((*itCam)->getName()); + } + m_attributesMap["attached_to_camera"] + ->editStringValuesChoices().assign(1, labels); + m_attributesMap["calibrate_with_camera"] + ->editStringValuesChoices().assign(1, labels); +} + +void ProjectorModule::attachToCam(const string& camName) { + if(m_space) { + if(m_attachedToCam) { + m_attachedToCam->detachProj(this); + } + m_attachedToCam = m_space->getDepthCamModule(camName); + if(m_attachedToCam) { + m_attachedToCam->attachProj(this); + } + } +} + +void ProjectorModule::setWindowDimensions(const int& x, const int& y, + const int& w, const int& h) { + glfwSetWindowPos(m_projWindow, x, y); + glfwSetWindowSize(m_projWindow, w, h); + m_width=w; + m_height=h; +} + +void ProjectorModule::setWindowDecoration(bool d) { + //m_window->setWindowDecoration(d); +} + +void ProjectorModule::fullscreenMonitor(const std::string& monitorName) { + int count; + GLFWmonitor** monitors = glfwGetMonitors(&count); + + GLFWmonitor* monitor = NULL; + for(int m=0; m<count; ++m) { + if(monitorName.compare(glfwGetMonitorName(monitors[m]))==0) { + monitor=monitors[m]; + } + } + + int posX=0; + int posY=0; + m_width=640; + m_height=480; + if(monitor) { + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + m_width=mode->width; + m_height=mode->height; + glfwGetMonitorPos(monitor, &posX, &posY); + } + m_posX=posX; + m_posY=posY; + glfwSetWindowMonitor(m_projWindow, monitor, 0, 0, + m_width, m_height, GLFW_DONT_CARE); + updateWindowDims(); + refreshMonitors(); +} + +void ProjectorModule::refreshMonitors(){ + int count; + GLFWmonitor** monitors = glfwGetMonitors(&count); + vector<string> monitorNames; + monitorNames.push_back("windowed"); + for(int m=0; m<count; ++m) { + monitorNames.push_back(glfwGetMonitorName(monitors[m])); + } + m_attributesMap["fullscreen_monitor"] + ->editStringValuesChoices().assign(count, monitorNames); +} + +void ProjectorModule::setViewMatrix(const vector<float>& vals) { + m_viewMat = mat4(vals[0], vals[1], vals[2], vals[3], + vals[4], vals[5], vals[6], vals[7], + vals[8], vals[9], vals[10], vals[11], + vals[12], vals[13], vals[14], vals[15]); + updateViewProjMatrix(); +} + +void ProjectorModule::setProjectionMatrix(const vector<float>& vals) { + m_projMat = mat4(vals[0], vals[1], vals[2], vals[3], + vals[4], vals[5], vals[6], vals[7], + vals[8], vals[9], vals[10], vals[11], + vals[12], vals[13], vals[14], vals[15]); + updateViewProjMatrix(); +} + +void ProjectorModule::updateModelMatrix() { + if(!m_attachedToCam) { + Module::updateModelMatrix(); + } + updateViewProjMatrix(); +} + +void ProjectorModule::setModelMat(const glm::mat4& mat) { + Module::setModelMat(mat); + updateViewProjMatrix(); +} + +void ProjectorModule::updateViewProjMatrix() { + m_transViewMat = m_modelMat * inverse(m_viewMat); + m_viewProjMat = m_projMat * inverse(m_transViewMat); +} + +void ProjectorModule::setModuleName(const string& name) { + Module::setModuleName(name); + glfwSetWindowTitle(m_projWindow, name.c_str()); + if(m_space) { + m_space->refreshProjList(); + } +} + +void ProjectorModule::outputRevealed(bool output) { + m_processOutput=output; +} + +void ProjectorModule::postFilter(const int& filt) { + m_postFilter=filt; +} + +void ProjectorModule::setTransparentWindow(const bool& transp) { + m_transparentBackground=transp; +} + +void ProjectorModule::processOutput() { + bool outputProcessed=false; + + //retrieve active revealed modules + vector<RevealedModule*>& revModules + = Reveal::getInstance()->editRegisteredOutputRevealed(); + vector<DepthCamModule*>& camModules + = Reveal::getInstance()->editRegisteredOutputDepthCams(); + + if(revModules.size()>0 || camModules.size()>0) { + //retrieve output image + glBindTexture(GL_TEXTURE_2D, m_outputTex); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, + GL_UNSIGNED_BYTE, + m_outputImg); + } + + + //process shape revealing output + if(revModules.size()>0) { + m_outNbDepth = m_space->getNbDepthModulesFromID(); + //get output values for revealed modules with active output + vector<RevealedModule*>::iterator itSh = revModules.begin(); + for(; itSh!=revModules.end(); ++itSh) { + //test if shape is visible from this projector + if((*itSh)->getVisibilityMask() & m_visibilityMask) { + for(int d=1; d<m_outNbDepth+1; ++d) { + DepthModule* mod = m_space->getDepthModuleFromID(d); + if(mod) { + if(mod->isDepthVisible(d)) { + (*itSh)->processReveal(d, + mod->getName(), + m_outNbDepth, + m_outputImg); + outputProcessed=true; + } + } + } + } + } + } + + /* + //process cam + if(camModules.size()>0) { + unsigned int curs; + vector<float> pos(3,0); + vector<DepthCamModule*>::iterator itCa = camModules.begin(); + for(; itCa!=camModules.end(); ++itCa) { + extractOutputValue((*itCa)->getDepthID()+500, 0, curs); + pos[0] = (int(curs) - int(curs/1000)*1000)*10-5000; + pos[1] = (int(curs/1000) - int(curs/1000000)*1000)*10-5000; + pos[2] = 10000-int(curs/1000000)*10; + //cout<<"got cursor "<<curs<<" from cam at pos " + // <<pos[0]<<" "<<pos[1]<<" "<<pos[2]<<endl; + (*itCa)->processCursor(pos); + } + outputProcessed=true; + } + */ + + if(outputProcessed) { + //reset output image to 0 + glBindTexture(GL_TEXTURE_2D, m_outputTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, + m_outputImgSize, m_outputImgSize, 0, + GL_RGBA, GL_UNSIGNED_BYTE, m_outputImgInit); + } +} + +void ProjectorModule::updateWindowSize(const int& w, const int& h) { + m_height=h; + m_width=w; + updateWindowDims(); +} + +void ProjectorModule::updateWindowPos(const int& x, const int& y) { + m_posX=x; + m_posY=y; + updateWindowDims(); +} + +void ProjectorModule::updateWindowDims() { + vector<int> dims(4,0); + dims[0]=m_posX; + dims[1]=m_posY; + dims[2]=m_width; + dims[3]=m_height; + m_attributesMap["window_dimensions"]->initInts(dims); + m_patternPosRange = Size(m_width, m_height); +} + +//-------------------------Calibration---------------------------------- + +/* +static void cbPatternSquareWidth(int w, void* mod) { + if(w>10) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + proj->setPatternSquareWidth(w); + } +}*/ + +void ProjectorModule::setPatternSquareWidth(const int& w) { + m_patternSquareWidth=w; + updateCalibrationPattern(); +} + +static void cbPatternPosOX(int x, void* mod) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + proj->setPatternPosOX(x); +} + +void ProjectorModule::setPatternPosOX(const int& x) { + m_patternPosOffset.width=x; + updateCalibrationPattern(); +} + +static void cbPatternPosOY(int y, void* mod) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + proj->setPatternPosOY(y); +} + +void ProjectorModule::setPatternPosOY(const int& y) { + m_patternPosOffset.height=y; + updateCalibrationPattern(); +} + +static void cbPatternPosRX(int x, void* mod) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + proj->setPatternPosRX(x); +} + +void ProjectorModule::setPatternPosRX(const int& x) { + m_patternPosRange.width=x; + updateCalibrationPattern(); +} + +static void cbPatternPosRY(int y, void* mod) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + proj->setPatternPosRY(y); +} + +void ProjectorModule::setPatternPosRY(const int& y) { + m_patternPosRange.height=y; + updateCalibrationPattern(); +} + +static void cbCalib(int c, void* mod) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + proj->setCalib(c); +} + +void ProjectorModule::setCalib(const int& c) { + if(m_calibrating==1 && c==0) { + m_calibrationStopped=true; + } + m_calibrating=c; +} + +static void cbPatternBrightness(int b, void* mod) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + proj->setPatternBrightness(b); +} + +void ProjectorModule::setPatternBrightness(const int& b) { + m_patternBrightness=b; +} + +void ProjectorModule::updateCalibrationPattern() { + m_generatedCorners.clear(); + for(int j=1; j<m_patternSize.height+1; ++j) { + for(int i=1; i<m_patternSize.width+1; ++i) { + int cornerX=m_patternSquareWidth*i+m_patternPosition.width; + int cornerY=m_patternSquareWidth*j+m_patternPosition.height; + m_generatedCorners.push_back(Point2f(cornerX, cornerY)); + } + } +} + +void ProjectorModule::calibrate(const std::string& camName) { + //get depth camera module and activate color image + DepthCamModule* cam = NULL; + if(m_space) { + cam = m_space->getDepthCamModule(camName); + } + if(cam==NULL) { + cout<<"No camera attached to projector"<<endl; + return; + } + + //close cam and reopen in calibration mode + cam->closeDevice(); + cam->openDevice(cam->getDeviceID(), true); + + //check cam is open + if(!cam->isOpen()) { + cout<<"Camera "<<cam->getName()<<"is not open"<<endl; + return; + } + + cout<<"Calibrating projector ..."<<endl; + + //create opencv windows, trackbars and initialize variables + m_imageSize = cv::Size(640 ,480); //fixme, get from cam color image size + m_calibrating=0; + m_calibrationStopped=false; + m_neededFramesNb=9; + cv::Mat kinectRgbImg = Mat::zeros(m_imageSize, CV_8UC3); + namedWindow("DepthCamRGB"); + namedWindow("Controls"); + createTrackbar("Pattern Offset X", "Controls", + &m_patternPosOffset.width, 1000, cbPatternPosOX, this); + createTrackbar("Pattern Offset Y", "Controls", + &m_patternPosOffset.height, 500, cbPatternPosOY, this); + createTrackbar("Pattern Range X", "Controls", + &m_patternPosRange.width, 1920, cbPatternPosRX, this); + createTrackbar("Pattern Range Y", "Controls", + &m_patternPosRange.height, 1080, cbPatternPosRY, this); + createTrackbar("Pattern Brightness", "Controls", + &m_patternBrightness, 100, cbPatternBrightness, this); + createTrackbar("Calibrate (1:Start, 0:Cancel)", "Controls", + NULL, 1, cbCalib, this); + vector<vector<Point3f> > objectPoints; + vector<vector<Point2f> > imagePoints; + Mat cameraMatrix = Mat::eye(3, 3, CV_64F); + Mat distCoeffs = Mat::zeros(8, 1, CV_64F); + vector<Mat> rvecs; + vector<Mat> tvecs; + + cam->activateColor(); + for(int f=0; f<m_neededFramesNb && !m_calibrationStopped;) { + //update pattern position + m_patternSquareWidth = m_height/20; + + m_patternPosition.width = (m_patternPosRange.width-m_patternSquareWidth) + / sqrt(m_neededFramesNb) + *(fmod(f,sqrt(m_neededFramesNb))) + +m_patternSquareWidth + +m_patternPosOffset.width; + + m_patternPosition.height=(m_patternPosRange.height-m_patternSquareWidth) + / sqrt(m_neededFramesNb) + *(floor(f/sqrt(m_neededFramesNb))) + +m_patternSquareWidth + +m_patternPosOffset.height; + updateCalibrationPattern(); + + //display frame with calibration pattern + glfwMakeContextCurrent(m_projWindow); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, m_width, m_height); + glDisable(GL_CULL_FACE); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + glUseProgram(m_programs[Reveal::CALIBPROG]); + glUniform1f(m_uniforms[Reveal::CALIBPROG][Reveal::VIEWPORTWIDTH], + m_width); + glUniform1f(m_uniforms[Reveal::CALIBPROG][Reveal::VIEWPORTHEIGHT], + m_height); + glUniform1f(m_uniforms[Reveal::CALIBPROG][Reveal::PATW], + m_patternSquareWidth); + glUniform1f(m_uniforms[Reveal::CALIBPROG][Reveal::PATPOSX], + m_patternPosition.width); + glUniform1f(m_uniforms[Reveal::CALIBPROG][Reveal::PATPOSY], + m_patternPosition.height); + glUniform2f(m_uniforms[Reveal::CALIBPROG][Reveal::PATOFFSET], + m_patternPosOffset.width, m_patternPosOffset.height); + glUniform2f(m_uniforms[Reveal::CALIBPROG][Reveal::PATRANGE], + m_patternPosRange.width, m_patternPosRange.height); + glUniform1f(m_uniforms[Reveal::CALIBPROG][Reveal::PATNBX], + m_patternSize.width); + glUniform1f(m_uniforms[Reveal::CALIBPROG][Reveal::PATNBY], + m_patternSize.height); + glUniform1f(m_uniforms[Reveal::CALIBPROG][Reveal::PATBRIGHT], + float(m_patternBrightness)/100.0); + m_calibGeom->drawDirect(m_contextHandlerID); + glfwSwapBuffers(m_projWindow); + + waitKey(10); + sleep(1); + + //grab frame + if(cam->getFrames()) { + openni::VideoFrameRef depthFrame = cam->getDepthFrame(); + openni::VideoFrameRef colorFrame = cam->getColorFrame(); + + //copy to opencv mat + for(int j=0; j<m_imageSize.height; ++j) { + for(int i=0; i<m_imageSize.width; ++i) { + cv::Vec3b& pix = kinectRgbImg.at<cv::Vec3b>(j,i); + int coord=0; + coord=j*m_imageSize.width+i; + openni::RGB888Pixel colorPix = + ((openni::RGB888Pixel*) colorFrame.getData())[coord]; + pix[0]=colorPix.r; + pix[1]=colorPix.g; + pix[2]=colorPix.b; + } + } + + + imshow("DepthCamRGB", kinectRgbImg); + if(m_calibrating) { + m_foundCorners.clear(); + //find chessboard in image + bool patternFound = findChessboardCorners( + kinectRgbImg, + m_patternSize, + m_foundCorners, + CALIB_CB_ADAPTIVE_THRESH); + //if we found it + if(patternFound) { + //refine + Mat gray; + cvtColor(kinectRgbImg, gray, COLOR_RGB2GRAY); + cornerSubPix(gray, m_foundCorners, + cv::Size(1, 1), cv::Size(-1, -1), + TermCriteria(TermCriteria::EPS, + 30, 0.1)); + + + bool validDepths=true; + //retrieve the corresponding position and depth + vector<Point3f> worldCorners; + vector<Point2f>::iterator itPnt=m_foundCorners.begin(); + for(; itPnt!=m_foundCorners.end(); ++itPnt) { + float posX, posY, posZ; + Point2f coord = Point2f((*itPnt).x,(*itPnt).y); + Point2f depthCoord = coord; + + openni::DepthPixel depthPix = + ((openni::DepthPixel*)depthFrame.getData())[int( + depthCoord.y*m_imageSize.width + + depthCoord.x)]; + posZ=depthPix; + + //filter the depth + int size=6; + vector<double> vals; + for(int x=depthCoord.x-size/2; + x<depthCoord.x+size/2; ++x) { + for(int y=depthCoord.y-size/2; + y<depthCoord.y+size/2; ++y) { + if(x>=0 && x<m_imageSize.width && + y>=0 && y<m_imageSize.height) { + vals.push_back( + ((openni::DepthPixel*)depthFrame.getData()) + [int(y*m_imageSize.width + x)]); + } + } + } + sort(vals.begin(), vals.end()); + posZ=vals[vals.size()/2]; + depthPix=posZ; + + openni::CoordinateConverter::convertDepthToWorld( + cam->getDepthStream(), + int(depthCoord.x), + int(depthCoord.y), + depthPix, + &posX, &posY, &posZ); + //if(reversed) { + // posX=-posX; + // posY=-posY; + //} + if(posZ<=500.0 || posZ>4000.0) { + validDepths=false; + } + else { + worldCorners.push_back(Point3f(posX, posY, posZ)); + } + } + + //if everything is valid + if(validDepths) { + cout<<"Pattern found "<<f<<"/"<<m_neededFramesNb<<endl; + //add the generated corners + imagePoints.push_back(m_generatedCorners); + cout<<m_generatedCorners[0]<<endl; + //add the detected world corners + objectPoints.push_back(worldCorners); + cout<<worldCorners[0]<<endl; + + //cout<<m_generatedCorners<<endl; + //cout<<worldCorners<<endl; + + //draw corners + drawChessboardCorners(kinectRgbImg, m_patternSize, + m_foundCorners, patternFound); + + + imshow("DepthCamRGB", kinectRgbImg); + waitKey(10); + + //wait + #ifdef POSIX + sleep(1); + #else + Sleep(1000); + #endif + + //increase frame count + ++f; + } + } + } + waitKey(10); + } + } + + double rms=0; + + if(objectPoints.size()>0) { + + //put the image and object points in the right order for opencv + vector<vector<Point3f> > vvo(1); //object points + vector<vector<Point2f> > vvi(1); //image points + for (unsigned int i=0; i<objectPoints.size(); ++i) { + for (unsigned int j = 0; j<objectPoints[i].size(); j++) { + vvo[0].push_back(objectPoints[i][j]); + vvi[0].push_back(imagePoints[i][j]); + } + } + + //when enough points found, get the extrinsics/intrisics parameter + float w = m_width; + float h = m_height; + cameraMatrix = (Mat1d(3, 3) << w, 0, w/2., + 0, h, h / 2., + 0, 0, 1); + distCoeffs = Mat::zeros(8, 1, CV_64F); + rms=calibrateCamera(vvo, vvi, + Size(w, h), cameraMatrix, + distCoeffs, rvecs, tvecs, + CALIB_FIX_K1+ + CALIB_FIX_K2+ + CALIB_FIX_K3+ + CALIB_FIX_K4+ + CALIB_FIX_K5+ + CALIB_FIX_K6+ + CALIB_ZERO_TANGENT_DIST+ + CALIB_USE_INTRINSIC_GUESS); + + cout<<"... done , RMS="<<rms<<endl; + + //Build the opengl view matrix + Mat rot; + rvecs[0].copyTo(rot); + Mat rotMat = Mat::zeros(3, 3, CV_64F); + Rodrigues(rot, rotMat); + + mat4 viewMatrix(rotMat.at<double>(0,0), rotMat.at<double>(1,0), + rotMat.at<double>(2,0), 0, + rotMat.at<double>(0,1), rotMat.at<double>(1,1), + rotMat.at<double>(2,1), 0, + rotMat.at<double>(0,2), rotMat.at<double>(1,2), + rotMat.at<double>(2,2), 0, + tvecs[0].at<double>(0,0), tvecs[0].at<double>(1,0), + tvecs[0].at<double>(2,0), 1); + + mat4 glCoordsMat(-1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + m_viewMat=glCoordsMat*viewMatrix; + + m_attributesMap["view_matrix"]->setFloats( + vector<float>( + value_ptr(m_viewMat), + value_ptr(m_viewMat)+16)); + //build the opengl projection matrix + double fx=cameraMatrix.at<double>(0,0); + double cx=cameraMatrix.at<double>(0,2); + double fy=cameraMatrix.at<double>(1,1); + double cy=cameraMatrix.at<double>(1,2); + double l=0; + double r=w; + double b=h; + double t=0; + double n=100; + double f=10000; + mat4 projMatrix( + 2.0*fx/w, 0, 0, 0, + 0, 2.0*fy/h, 0, 0, + 1.0-2.0*(cx)/w,-1.0+(2.0*(cy)+2.0)/h, (f+n)/(n-f), -1, + 0, 0, (2.0*f*n)/(n-f), 0); + m_attributesMap["projection_matrix"]->setFloats( + vector<float>(value_ptr(projMatrix), + value_ptr(projMatrix)+16)); + m_attributesMap["attached_to_camera"] + ->setStrings(vector<string>(1, cam->getName())); + } + + ostringstream oss; + oss<<rms; + + cv::Mat reconstructionImg = Mat::zeros(Size(m_width, m_height), CV_8UC3); + + //project reconstructed kinect + while(!m_calibrationStopped) { + if(cam->getFrames()) { + openni::VideoFrameRef depthFrame = cam->getDepthFrame(); + openni::VideoFrameRef colorFrame = cam->getColorFrame(); + + //get points from the kinect and their actual 3D positions + reconstructionImg.setTo(cv::Vec3b(0,0,0)); + vector<Point3f> objPnts; + vector<cv::Vec3b> kinPnts; + vector<Point2f> imgPnts; + for(int j=0; j<m_imageSize.height; ++j) { + for(int i=0; i<m_imageSize.width; ++i) { + float posX, posY, posZ; + int coord = m_imageSize.width*j+i; + openni::DepthPixel depthPix = + ((openni::DepthPixel*)depthFrame.getData())[coord]; + openni::CoordinateConverter::convertDepthToWorld( + cam->getDepthStream(), + i, j, depthPix, + &posX, &posY, &posZ); + objPnts.push_back(Point3f(posX,posY,posZ)); + const openni::RGB888Pixel& colorPix = + ((openni::RGB888Pixel*) colorFrame.getData())[coord]; + kinPnts.push_back(cv::Vec3b(colorPix.r, + colorPix.g, + colorPix.b)); + } + } + projectPoints(objPnts, rvecs[0], tvecs[0], + cameraMatrix, distCoeffs, imgPnts); + + //for each of the image points + vector<Point2f>::iterator itPnt=imgPnts.begin(); + vector<cv::Vec3b>::iterator itKin=kinPnts.begin(); + vector<Point3f>::iterator itObj=objPnts.begin(); + for(; itPnt!=imgPnts.end() && itKin!=kinPnts.end(); + ++itPnt, ++itKin, ++itObj) { + if((*itPnt).x<reconstructionImg.cols && + (*itPnt).y<reconstructionImg.rows && + (*itPnt).x>0 && + (*itPnt).y>0) { + reconstructionImg.at<cv::Vec3b>( + (*itPnt).y, + (*itPnt).x) + =(*itKin); + } + } + + putText(reconstructionImg, "RMS="+oss.str(), Point(0,50), + cv::FONT_HERSHEY_SIMPLEX, 2, + Scalar(255, 255, 255)); + imshow( "DepthCamRGB", reconstructionImg); + } + waitKey(10); + } + + //close opencv windows + destroyWindow("DepthCamRGB"); + destroyWindow("Controls"); + waitKey(10); + + //reopen cam in normal mode + cam->closeDevice(); + cam->openDevice(cam->getDeviceID()); +} + +void ProjectorModule::calibrateCamWithMarker(const std::string& camName) { + + + +} + diff --git a/src/modules/ProjectorModule.hpp b/src/modules/ProjectorModule.hpp new file mode 100644 index 0000000..3cbdf06 --- /dev/null +++ b/src/modules/ProjectorModule.hpp @@ -0,0 +1,227 @@ +/*************************************************************************** + * ProjectorModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef ProjectorModule_h +#define ProjectorModule_h + +#include "GroupModule.hpp" +#include <iostream> +#include <pthread.h> + +#include "opencv2/highgui/highgui.hpp" +#include "opencv2/calib3d/calib3d.hpp" + +#include "../geoms/QuadGeometry.hpp" + +#include "../Reveal.hpp" + +class SpaceModule; +class DepthCamModule; + +class ProjectorModule : public Module, public ContextHandler { + public: + ProjectorModule(); + virtual ~ProjectorModule(); + virtual void draw(); + void deleteModule(); + + static void activeCallback(Module* mod, + const std::vector<bool>& vals) { + static_cast<ProjectorModule*>(mod)->setActive(vals[0]); + } + inline void setActive(bool active) {m_active=active;} + static void calibrateCallback(Module* mod, + const std::vector<std::string>& vals) { + static_cast<ProjectorModule*>(mod)->calibrate(vals[0]); + } + void calibrate(const std::string& camName); + void calibrateCamWithMarker(const std::string& camName); + static void windowDimensionsCallback(Module* mod, + const std::vector<int>& vals) { + static_cast<ProjectorModule*>(mod)->setWindowDimensions(vals[0], + vals[1], + vals[2], + vals[3]); + } + void setWindowDimensions(const int& x, const int& y, + const int& w, const int& h); + static void windowSizeCallback(GLFWwindow* win, int w, int h) { + static_cast<ProjectorModule*>(glfwGetWindowUserPointer(win)) + ->updateWindowSize(w, h); + } + static void framebufferSizeCallback(GLFWwindow* win, int w, int h) { + static_cast<ProjectorModule*>(glfwGetWindowUserPointer(win)) + ->updateWindowSize(w, h); + } + void updateWindowSize(const int& w, const int& h); + static void windowPositionCallback(GLFWwindow* win, int x, int y) { + static_cast<ProjectorModule*>(glfwGetWindowUserPointer(win)) + ->updateWindowPos(x, y); + } + void updateWindowPos(const int& x, const int& y); + void updateWindowDims(); + + static void windowDecorationCallback(Module* mod, + const std::vector<bool>& vals) { + static_cast<ProjectorModule*>(mod)->setWindowDecoration(vals[0]); + } + void setWindowDecoration(bool d); + static void fullscreenMonitorCallback(Module* mod, + const std::vector<std::string>& vals) { + static_cast<ProjectorModule*>(mod)->fullscreenMonitor(vals[0]); + } + void fullscreenMonitor(const std::string& monitor); + static void viewMatrixCallback(Module* mod, + const std::vector<float>& vals) { + static_cast<ProjectorModule*>(mod)->setViewMatrix(vals); + } + void setViewMatrix(const std::vector<float>& vals); + static void projectionMatrixCallback(Module* mod, + const std::vector<float>& vals) { + static_cast<ProjectorModule*>(mod)->setProjectionMatrix(vals); + } + void setProjectionMatrix(const std::vector<float>& vals); + static void attachToCamCallback(Module* mod, + const std::vector<std::string>& vals) { + static_cast<ProjectorModule*>(mod)->attachToCam(vals[0]); + } + void attachToCam(const std::string& camName); + static void outputRevealedCallback(Module* mod, + const std::vector<bool>& vals) { + static_cast<ProjectorModule*>(mod)->outputRevealed(vals[0]); + } + void outputRevealed(bool output); + static void mirroredCallback(Module* mod, + const std::vector<bool>& vals) { + static_cast<ProjectorModule*>(mod)->setMirrored(vals[0]); + } + inline void setMirrored(bool m){m_mirrored=m;} + + static void postFilterCallback(Module* mod, + const std::vector<int>& vals) { + static_cast<ProjectorModule*>(mod)->postFilter(vals[0]); + } + void postFilter(const int& filt); + + static void transparentWindowCallback(Module* mod, + const std::vector<bool>& vals) { + static_cast<ProjectorModule*>(mod)->setTransparentWindow(vals[0]); + } + void setTransparentWindow(const bool& transp); + + + void setPatternSquareWidth(const int&); + void setPatternPosOX(const int&); + void setPatternPosOY(const int&); + void setPatternPosRX(const int&); + void setPatternPosRY(const int&); + void setPatternPositionY(const int&); + void setPatternBrightness(const int&); + void setCalib(const int&); + void setModuleName(const std::string&); + + inline const bool& getMirrored(){return m_mirrored;} + + void setSpace(SpaceModule* space); + virtual void setModelMat(const glm::mat4& mat); + void updateModelMatrix(); + void updateViewProjMatrix(); + inline void setProjID(const int& id){m_projID=id;} + inline const int& getProjID(){return m_projID;} + + void refreshMonitors(); + + void refreshDepthCamList(const std::vector<DepthCamModule*>); + void processOutput(); + + private: + void initGL(); + void createRTT(GLuint& tex, GLuint& fbo, + const int& width, const int& height, bool filter); + + void updateCalibrationPattern(); + + + private: + int m_projID; + GLFWwindow* m_projWindow; + SpaceModule* m_space; + DepthCamModule* m_attachedToCam; + DepthCamModule* m_calibrationCam; + glm::mat4 m_transViewMat; + bool m_initialized; + bool m_mirrored; + bool m_active; + GLuint m_selectTex; + GLuint m_selectFBO; + GLuint m_sliceTex; + GLuint m_sliceRttTex; + GLuint m_sliceSmpTex; + GLuint m_sliceFBO; + GLuint m_renderTex; + GLuint m_renderFBO; + float m_posX, m_posY; + int m_rttWidth, m_rttHeight; + bool m_processOutput; + float m_postFilter; + bool m_transparentBackground; + + QuadGeometry* m_calibGeom; + + //calibration + cv::Mat m_projectedImg; + std::vector<cv::Point2f> m_foundCorners; + cv::Size m_patternSize; + int m_patternSquareWidth; + int m_patternThresh; + cv::Size m_patternPosOffset; + cv::Size m_patternPosRange; + cv::Size m_patternPosition; + int m_neededFramesNb; + std::vector<cv::Point2f> m_generatedCorners; + bool m_calibrated; + int m_calibrating; + int m_patternBrightness; + bool m_calibrationStopped; + cv::Size m_imageSize; + + //shader/programs + std::map<Reveal::REVIL_PROGRAM, GLint> m_programs; + std::map<Reveal::REVIL_PROGRAM, + std::map<Reveal::REVIL_UNIFORM, GLint> > m_uniforms; + + //output + GLuint m_outputTex; + static const unsigned int m_outputImgSize=500; + unsigned int* m_outputImg; + unsigned int* m_outputImgInit; + int m_outShapeSize; + int m_outVoxelSize; + int m_outHistoSize; + int m_outDepthSize; + int m_outNbDepth; +}; + + +#endif + diff --git a/src/modules/RevealedArrowModule.cpp b/src/modules/RevealedArrowModule.cpp new file mode 100644 index 0000000..32d96e2 --- /dev/null +++ b/src/modules/RevealedArrowModule.cpp @@ -0,0 +1,348 @@ +/*************************************************************************** + * RevealedArrowModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "RevealedArrowModule.hpp" + +#include "../geoms/Geometry.hpp" + +#include <glm/gtx/matrix_decompose.hpp> +#include <glm/gtx/quaternion.hpp> +#include <glm/gtx/polar_coordinates.hpp> +#include <glm/gtx/rotate_vector.hpp> +#include <glm/gtx/euler_angles.hpp> + +using namespace std; + +RevealedArrowModule::RevealedArrowModule(): GroupModule() { + m_type="Arrow"; + m_name="arrow"; + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + addVisibleFromAttribute(); + + addAttribute(new Attribute("origin_module", + Attribute::STRING_ATTRIBUTE, + originModuleCallback, this, 1)); + addAttribute(new Attribute("origin_offset", + Attribute::FLOAT_ATTRIBUTE, + originOffsetCallback, this, 3)); + addAttribute(new Attribute("destination_module", + Attribute::STRING_ATTRIBUTE, + destinationModuleCallback, this, 1)); + addAttribute(new Attribute("destination_offset", + Attribute::FLOAT_ATTRIBUTE, + destinationOffsetCallback, this, 3)); + addAttribute(new Attribute("elements_number", + Attribute::INT_ATTRIBUTE, + elementsNumberCallback, this, 1)); + addAttribute(new Attribute("elements_speed", + Attribute::FLOAT_ATTRIBUTE, + elementsSpeedCallback, this, 1)); + addAttribute(new Attribute("elements_thickness", + Attribute::FLOAT_ATTRIBUTE, + elementsThicknessCallback, this, 1)); + addAttribute(new Attribute("elements_direction", + Attribute::FLOAT_ATTRIBUTE, + elementsDirectionCallback, this, 3)); + addAttribute(new Attribute("follow_direction", + Attribute::BOOL_ATTRIBUTE, + followDirectionCallback, this, 1)); + + addAttribute(new Attribute("revealed_elements", + Attribute::FLOAT_ATTRIBUTE, + elementsRevealedCallback, this, 1)); + m_revAttributes.push_back(m_attributesMap["revealed_elements"]); + + m_thickness=0.5; + m_followDirection=false; + m_origPnt = new ArrowPoint(this); + m_destPnt = new ArrowPoint(this); + + m_nbElements=0; + m_attributesMap["elements_number"]->setInts(vector<int>(1, 10)); + m_attributesMap["elements_thickness"]->setFloats(vector<float>(1, 0.2)); + m_attributesMap["elements_speed"]->setFloats(vector<float>(1, 5)); + vector<float> dir(3,0); + dir[2]=-1; + m_attributesMap["elements_direction"]->setFloats(dir); + m_distance=0; + + m_attributesMap["origin_offset"]->setFloats(vector<float>(3,0)); + m_attributesMap["destination_offset"]->setFloats(vector<float>(3,0)); + + m_revealed.push_back(0); + m_revealedChanged=false; + + Reveal::getInstance()->addModuleListObserver(this); + Reveal::getInstance()->addUpdateObserver(this); +} + +RevealedArrowModule::~RevealedArrowModule() { +} + +void RevealedArrowModule::deleteModule() { + GroupModule::deleteModule(); + for(int i=0; i<m_nbElements; ++i) { + m_elements[i]->deleteModule(); + } +} + +void RevealedArrowModule::draw() { +} + +void RevealedArrowModule::setVisible(bool vis) { + GroupModule::setVisible(vis); + for(int i=0; i<m_nbElements; ++i) { + m_elements[i]->setParentVisible(m_parentVisible&&m_visible); + } +} + +void RevealedArrowModule::setOriginModule(const std::string& moduleStr) { + Module* mod = NULL; + mod = Reveal::getInstance()->findModule(moduleStr); + m_origModStr=moduleStr; + if(mod) { + m_origPnt->setModule(mod); + mod->getAttribute("absolute_position")->addListener(m_origPnt); + } + updateArrowPoints(); +} + +void RevealedArrowModule::setOriginOffset(const float& x, + const float& y, + const float& z) { + m_originOffset[0]=x; + m_originOffset[1]=y; + m_originOffset[2]=z; + updateArrowPoints(); +} + +void RevealedArrowModule::setDestinationModule(const std::string& moduleStr) { + Module* mod = NULL; + mod = Reveal::getInstance()->findModule(moduleStr); + m_destModStr=moduleStr; + if(mod) { + m_destPnt->setModule(mod); + mod->getAttribute("absolute_position")->addListener(m_destPnt); + } + updateArrowPoints(); +} + +void RevealedArrowModule::setDestinationOffset(const float& x, + const float& y, + const float& z) { + m_destOffset[0]=x; + m_destOffset[1]=y; + m_destOffset[2]=z; + updateArrowPoints(); +} + +void RevealedArrowModule::setElementsNumber(const int& nb) { + if(nb>0) { + if(nb>m_nbElements) { + for(int i=m_nbElements; i<nb; ++i) { + m_elements.push_back(new ArrowElementModule(m_elements.size(), + this)); + m_elements.back()->setShape("cone"); + m_elements.back()->setSurfaceThickness(5); + m_elements.back()->setInsideVisible(false); + m_elements.back()->setGradientType("along_y"); + m_positions.push_back(0); + } + } + m_nbElements=nb; + for(int i=0; i<m_nbElements; ++i) { + m_elements[i]->setVisible(true); + } + for(unsigned int i=m_nbElements; i<m_elements.size(); ++i) { + m_elements[i]->setVisible(false); + } + updateArrowPoints(); + } +} + +void RevealedArrowModule::setElementsSpeed(const float& sp) { + if(sp>=0) { + m_speed=sp/1000; + updateArrowPoints(); + } +} + +void RevealedArrowModule::setThickness(const float& th) { + if(th>0) { + m_thickness=th; + updateArrowPoints(); + } +} + +void RevealedArrowModule::setElementsDirection(const float& x, + const float& y, + const float& z) { + m_elementsDirection[0]=x; + m_elementsDirection[1]=y; + m_elementsDirection[2]=z; + updateArrowPoints(); +} + +void RevealedArrowModule::setFollowDirection(bool f) { + m_followDirection=f; + updateArrowPoints(); +} + +void RevealedArrowModule::update(const int& timeDiffMs) { + if(m_visible) { + if(m_speed>0) { + for(int i=0; i<m_nbElements; ++i) { + m_positions[i]=fmod(m_positions[i]+m_speed,1); + float pos = m_positions[i]*m_distance; + m_elements[i]->setPosition(m_origin[0]+m_dir[0]*pos, + m_origin[1]+m_dir[1]*pos, + m_origin[2]+m_dir[2]*pos); + } + } + if(m_revealedChanged) { + m_revealed[0]=0; + for(int i=0; i<m_nbElements; ++i) { + if(m_elements[i]->isRevealed()>0) { + m_revealed[0]=1; + } + } + m_attributesMap["revealed_elements"]->setFloatsIfChanged(m_revealed); + m_revealedChanged=false; + } + } +} + + +void RevealedArrowModule::updateModulesList(const map<string, Module*>& mods) { + vector<vector<string> >& oriModNames = m_attributesMap["origin_module"] + ->editStringValuesChoices(); + vector<vector<string> >& desModNames = m_attributesMap["destination_module"] + ->editStringValuesChoices(); + oriModNames.clear(); + desModNames.clear(); + oriModNames.push_back(vector<string>()); + desModNames.push_back(vector<string>()); + map<string, Module*>::const_iterator itMod = mods.begin(); + for(; itMod!=mods.end(); ++itMod) { //select names from scene modules + if(itMod->first.find("/revil/scene/")==0 + && itMod->first.compare(m_fullName)!=0) { + oriModNames[0].push_back(itMod->first); + desModNames[0].push_back(itMod->first); + } + } + setOriginModule(m_origModStr); + setDestinationModule(m_destModStr); +} + +void RevealedArrowModule::updateArrowPoints() { + if(m_origPnt->getModule()!=NULL + && m_destPnt->getModule()!=NULL) { + + const vector<float>& floatValues1 + =m_origPnt->getModule()->getAttribute("absolute_position")->getFloats(); + for(int i=0; i<3; ++i) { + m_origin[i]=floatValues1[i]+m_originOffset[i]; + } + + const vector<float>& floatValues2 + =m_destPnt->getModule()->getAttribute("absolute_position")->getFloats(); + for(int i=0; i<3; ++i) { + m_dest[i]=floatValues2[i]+m_destOffset[i]; + } + + m_dir = m_dest - m_origin; + m_distance=length(m_dir); + m_dir = glm::normalize(m_dir); + + glm::quat q; + glm::vec3 up(0,1,0); + getQuatFromTwoVecs(q, up, m_dir); + //glm::vec3 e = glm::eulerAngles(q); + for(int i=0; i<m_nbElements; ++i) { + m_positions[i]=(float(i)+0.5)/float(m_nbElements); + float pos = m_positions[i]*m_distance; + m_elements[i]->setPosition(m_origin[0]+m_dir[0]*pos, + m_origin[1]+m_dir[1]*pos, + m_origin[2]+m_dir[2]*pos); + if(m_followDirection) { + m_elements[i]->setQuaternion(q[0],q[1],q[2],q[3]); + m_elements[i]->setScale(m_thickness, + (m_distance/float(m_nbElements))/200, + m_thickness); + } + else { + glm::quat q2; + getQuatFromTwoVecs(q2, up, m_elementsDirection); + m_elements[i]->setQuaternion(q2[0],q2[1],q2[2],q2[3]); + m_elements[i]->setScale((m_distance/float(m_nbElements))/200, + m_thickness, + (m_distance/float(m_nbElements))/200); + } + } + } +} + +void RevealedArrowModule::gotAttributeListenersUpdate(Attribute* att) { + bool active=false; + vector<Attribute*>::iterator itAtt = m_revAttributes.begin(); + for(; itAtt!=m_revAttributes.end(); ++itAtt) { + if((*itAtt)->editListeners().size()>0) { + active=true; + } + } + if(active) { + for(int i=0; i<m_nbElements; ++i) { + Reveal::getInstance()->registerOutputRevealed(m_elements[i]); + } + } + else { + for(int i=0; i<m_nbElements; ++i) { + Reveal::getInstance()->unregisterOutputRevealed(m_elements[i]); + } + } +} + +void RevealedArrowModule::processRevealedElement() { + m_revealedChanged=true; +} + +ArrowPoint::ArrowPoint(RevealedArrowModule* mod) { + m_saved=false; + m_arrowMod=mod; + m_mod=NULL; +} + +void ArrowPoint::setModule(Module* mod) { + m_mod=mod; +} + +void ArrowPoint::update(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues) { + m_arrowMod->updateArrowPoints(); +} + + diff --git a/src/modules/RevealedArrowModule.hpp b/src/modules/RevealedArrowModule.hpp new file mode 100644 index 0000000..b59b79a --- /dev/null +++ b/src/modules/RevealedArrowModule.hpp @@ -0,0 +1,199 @@ +/*************************************************************************** + * RevealedArrowModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef RevealedArrowModule_h +#define RevealedArrowModule_h + +#include "GroupModule.hpp" +#include "RevealedShapeModule.hpp" + +class ArrowPoint; +class ArrowElementModule; + +class RevealedArrowModule : public GroupModule, + public ModuleListObserver { + public: + RevealedArrowModule(); + virtual ~RevealedArrowModule(); + virtual void deleteModule(); + + void draw(); + void setVisible(bool vis); + + static void originModuleCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedArrowModule*>(mod)->setOriginModule(vals[0]); + } + void setOriginModule(const std::string& mod); + + static void originOffsetCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedArrowModule*>(mod)->setOriginOffset( + vals[0], + vals[1], + vals[2]); + } + void setOriginOffset(const float& x, + const float& y, + const float& z); + + static void destinationModuleCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedArrowModule*>(mod) + ->setDestinationModule(vals[0]); + } + void setDestinationModule(const std::string& mod); + + static void destinationOffsetCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedArrowModule*>(mod)->setDestinationOffset( + vals[0], + vals[1], + vals[2]); + } + void setDestinationOffset(const float& x, + const float& y, + const float& z); + + static void elementsNumberCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<RevealedArrowModule*>(mod)->setElementsNumber(vals[0]); + } + void setElementsNumber(const int& mod); + + static void elementsSpeedCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedArrowModule*>(mod)->setElementsSpeed(vals[0]); + } + void setElementsSpeed(const float& mod); + + static void elementsThicknessCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedArrowModule*>(mod)->setThickness(vals[0]); + } + void setThickness(const float& th); + + static void elementsDirectionCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedArrowModule*>(mod)->setElementsDirection( + vals[0], + vals[1], + vals[2]); + } + void setElementsDirection(const float& x, + const float& y, + const float& z); + + static void followDirectionCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<RevealedArrowModule*>(mod)->setFollowDirection(vals[0]); + } + void setFollowDirection(bool f); + + static void elementsRevealedCallback(Module* mod, + const std::vector<float>& vals) {} + void processRevealedElement(); + + + void update(const int& timeDiffMs); + virtual void updateModulesList(const std::map<std::string, Module*>&); + + void gotAttributeListenersUpdate(Attribute* att); + void updateArrowPoints(); + + protected: + int m_nbElements; + float m_speed; + ArrowPoint* m_origPnt; + ArrowPoint* m_destPnt; + glm::vec3 m_origin; + glm::vec3 m_originOffset; + glm::vec3 m_dest; + glm::vec3 m_destOffset; + glm::vec3 m_dir; + float m_distance; + std::vector<ArrowElementModule*> m_elements; + std::vector<float> m_positions; + std::string m_origModStr; + std::string m_destModStr; + float m_thickness; + glm::vec3 m_elementsDirection; + bool m_followDirection; + std::vector<Attribute*> m_revAttributes; + std::vector<float> m_revealed; + bool m_revealedChanged; +}; + +class ArrowPoint : public Listener { + public: + ArrowPoint(RevealedArrowModule*); + void setModule(Module* mod); + inline Module* getModule(){return m_mod;} + void update(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues); + private: + RevealedArrowModule* m_arrowMod; + Module* m_mod; +}; + +class ArrowElementModule : public RevealedShapeModule { + public: + ArrowElementModule( const int& elID, + RevealedArrowModule* arr) : RevealedShapeModule(), + m_elementID(elID), + m_arrow(arr), + m_revealed(0) { + } + + + virtual void processReveal(const unsigned int& id, + const std::vector<std::string>& name, + const std::vector<float>& surface, + const std::vector<float>& inside, + const std::vector<float>& center, + const std::vector<float>& extent, + const std::vector<float>& color, + const std::vector<float>& blob) { + + if(m_revealed!=inside[0]) { + m_revealed=inside[0]; + m_arrow->processRevealedElement(); + } + } + + inline const float& isRevealed(){return m_revealed;} + + private: + int m_elementID; + int m_elementRevealed; + RevealedArrowModule* m_arrow; + float m_revealed; + +}; + + + +#endif + diff --git a/src/modules/RevealedCutModule.cpp b/src/modules/RevealedCutModule.cpp new file mode 100644 index 0000000..a2cbc28 --- /dev/null +++ b/src/modules/RevealedCutModule.cpp @@ -0,0 +1,393 @@ +/*************************************************************************** + * RevealedCutModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "RevealedCutModule.hpp" + +#include <iostream> +#include <glm/gtx/quaternion.hpp> + +#include "../Reveal.hpp" + +#include "../geoms/Geometry.hpp" + +using namespace std; + +RevealedCutModule::RevealedCutModule(): ShapeModule(), RevealedModule() { + m_type="Cut"; + m_name="cut"; + m_cutWin=NULL; + m_updateOnce=false; + + Reveal::getInstance()->getGeom(Reveal::GEOM_BOX)->registerModule(this); + + m_layersNb=1; + int nbBytes = m_texWidth*m_texHeight*m_layersNb*3; + m_layersData = new char[nbBytes]; + m_coordImage = new float[m_texWidth*m_texHeight*2]; + + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + addVisibleFromAttribute(); + addRevealedByAttribute(); + + //add cut attributes + addAttribute(new Attribute("refresh_windows", + Attribute::ACTION_ATTRIBUTE, + refreshWindowsCallback, this)); + addAttribute(new Attribute("window", + Attribute::STRING_ATTRIBUTE, + windowCallback, this, 1)); + addAttribute(new Attribute("selection_position", + Attribute::INT_ATTRIBUTE, + selPosCallback, this, 2)); + addAttribute(new Attribute("selection_size", + Attribute::INT_ATTRIBUTE, + selSizeCallback, this, 2)); + addAttribute(new Attribute("update_once", + Attribute::BOOL_ATTRIBUTE, + updateOnceCallback, this, 1)); + refreshWindows(); + + addTransformationAttributes(); + addRevealedAttributes(); + addRevealedOutputAttributes(); + m_inside=9; + m_localInsideAxes=true; + + Reveal::getInstance()->addUpdateObserver(this); +} + +RevealedCutModule::~RevealedCutModule() { + Reveal::getInstance()->getGeom(Reveal::GEOM_BOX)->unregisterModule(this); + Reveal::getInstance()->removeUpdateObserver(this); +} + +void RevealedCutModule::refreshWindows() { + CutWindowsManager* winsMan = CutWindowsManager::getInstance(); + winsMan->updateWindowsList(); + + vector<string> names; + names.push_back("none"); + vector<CutWindow*>& wins = winsMan->editWindowList(); + vector<CutWindow*>::iterator itWin = wins.begin(); + for(; itWin!=wins.end(); ++itWin) { + names.push_back(((*itWin)->getName()).c_str()); + } + m_attributesMap["window"]->editStringValuesChoices().assign(1,names); + m_attributesMap["window"]->initStrings(vector<string>(1, names[0])); +} + +void RevealedCutModule::setWindow(const std::string& winName) { + CutWindow* win = CutWindowsManager::getInstance()->getWindow(winName); + m_cutWin=win; + if(m_cutWin) { + m_nbPixPerRow = m_cutWin->computeNbPixPerRow(200, 100); + vector<int> coords(2,0); + m_attributesMap["selection_position"]->initInts(coords); + coords[0]=m_cutWin->getWidth(); + coords[1]=m_cutWin->getHeight(); + m_attributesMap["selection_size"]->initInts(coords); + m_winX=0; + m_winY=0; + m_winW=m_cutWin->getWidth(); + m_winH=m_cutWin->getHeight(); + recomputePixels(); + } +} + +void RevealedCutModule::selPos(const int& posX, const int& posY) { + m_winX=posX; + m_winY=posY; + recomputePixels(); +} + +void RevealedCutModule::selSize(const int& sizeX, const int& sizeY) { + m_winW=sizeX; + m_winH=sizeY; + recomputePixels(); +} + +void RevealedCutModule::updateOnce(bool upOn) { + m_updateOnce=upOn; + m_updateOnceDone=false; +} + +void RevealedCutModule::recomputePixels() { + //if window attached, recompute correspondance between pixel coordinates + if(m_cutWin) { + //get new pixperrow in window + m_nbPixPerRow = m_cutWin->computeNbPixPerRow(m_winW, + m_winH); + //clear existing coordinates + vector<float> coord(2,0); + vector<float> start(2,0); + vector<bool> restart(2,false); + vector<float> stepY(2,0); + vector<float> stepX(2,0); + + //compute the pixels offset and steps + start[0]=m_winX; + start[1]=m_winY; + restart[0]=true; + stepX[0]=float(m_winW)/float(m_texWidth); + stepY[1]=float(m_winH)/float(m_texHeight); + + vector<int> intCoord(2, 0); + coord[0]=start[0]; + coord[1]=start[1]; + + //compute coordinates according to shape + for(int py = 0; py < m_texHeight; py++) { + coord[0]=restart[0]?start[0]:coord[0]; + coord[1]=restart[1]?start[1]:coord[1]; + for(int px = 0; px < m_texWidth; px++) { + intCoord[0]=coord[0]; + intCoord[1]=coord[1]; + coord[0]+=stepX[0]; + coord[1]+=stepX[1]; + m_coordImage[(m_texWidth*py+px)*2]=float(intCoord[0]) + / float(m_cutWin->getWidth()); + m_coordImage[(m_texWidth*py+px)*2+1]=float(intCoord[1]) + / float(m_cutWin->getHeight()); + } + coord[0]+=stepY[0]; + coord[1]+=stepY[1]; + } + //ask for reinitializing texture uniform + map<int, bool>::iterator itUp = m_coordsUpMap.begin(); + for(; itUp!=m_coordsUpMap.end(); ++itUp) { + itUp->second=true; + } + } + m_updateOnceDone=false; +} + +void RevealedCutModule::draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& comp){ + + RevealedModule::draw(contextID, prog, uniforms, comp); + if(m_cutWin && prog==Reveal::RENDERPROG) { + glUniform1i(uniforms[Reveal::INSIDETEX], 2); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_3D, m_insideIDMap[contextID]); + if(!m_updateOnce || (m_updateOnce && !m_updateOnceDone)) { + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, + m_nbPixPerRow, m_cutWin->getHeight(), + m_layersNb, 0, + GL_RGBA, GL_UNSIGNED_BYTE, + m_cutWin->grabImage()); + m_updateOnceDone=true; + } + + glUniform1i(uniforms[Reveal::COORDSTEX], 4); + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, m_coordsIDMap[contextID]); + if(m_coordsUpMap[contextID]) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, + m_texWidth, m_texHeight, + 0, GL_RG, GL_FLOAT, + m_coordImage); + m_coordsUpMap[contextID]=false; + } + } +} + +void RevealedCutModule::update(const int& timeDiffMs) { + if(m_cutWin) { + m_cutWin->releaseImage(); + } +} + +//Window manager +#ifdef LINUX +CutWindow::CutWindow(CutWindowsManager* man, + Display* disp, + const Window& win): m_winsMan(man), + m_disp(disp), + m_win(win) { + Window root; + unsigned int bw, d, w, h; + XGetGeometry(m_disp, m_win, &root, &m_posX, &m_posY, + &w, &h, &bw, &d); + m_width=w; + m_height=h; + m_offsetX=0; + m_offsetY=0; + m_pixPerRow=m_width; + m_grabbed=false; + m_init=false; + m_defaultImgData = new uchar[m_width*m_height*3]; +} +#endif + +void CutWindow::releaseImage() { +#ifdef LINUX + if(m_grabbed) { + if(m_ximg) { + //XDestroyImage(m_ximg); + } + m_grabbed=false; + } +#endif +} + +uchar* CutWindow::grabImage() { +#ifdef LINUX + if(!m_grabbed) { + //XImage* newImg = XGetImage(m_disp, m_win, + // 0, 0, + // m_width, m_height, + // AllPlanes, ZPixmap); + XImage* newImg=NULL; + if(!m_init) { + newImg = XGetImage(m_disp, m_win, + 0, 0, + m_width, m_height, + AllPlanes, ZPixmap); + if(newImg) { + m_ximg=newImg; + m_init=true; + } + } + else { + newImg = XGetSubImage(m_disp, m_win, + 0, 0, + m_width, m_height, + AllPlanes, ZPixmap, + m_ximg, 0, 0); + } + if(newImg) { + m_imgData=(uchar*)m_ximg->data; + } + else { + m_imgData=m_defaultImgData; + } + m_grabbed=true; + } +#endif + return m_imgData; +} + +int CutWindow::computeNbPixPerRow(const int& srcW, const int& srcH) { +#ifdef LINUX + XWindowAttributes attrs; + XGetWindowAttributes(m_disp, m_win, &attrs); + m_width=attrs.width; + m_height=attrs.height; + m_pixPerRow=m_width; + return m_width; +#else + return 100; +#endif +} + +CutWindowsManager* CutWindowsManager::getInstance() { + static CutWindowsManager winsMan; + return &winsMan; +} + +CutWindowsManager::CutWindowsManager() { +#ifdef LINUX + m_disp = XOpenDisplay(NULL); +#endif +} + +CutWindowsManager::~CutWindowsManager() { +#ifdef LINUX + XCloseDisplay(m_disp); +#endif +} + +void CutWindowsManager::updateWindowsList() { + map<string, CutWindow*> prevWins; + vector<CutWindow*>::iterator itWin=m_windowList.begin(); + for(; itWin!=m_windowList.end(); ++itWin) { + prevWins[(*itWin)->getName()]=(*itWin); + } + m_windowList.clear(); + unsigned long len; + +#ifdef LINUX + Window *list = getWinList(m_disp, &len); + for(int i=0;i<(int)len;i++) { + char* name = getWinName(m_disp, list[i]); + CutWindow* newWin=NULL; + if(prevWins.find(string(name))!=prevWins.end()) { + newWin = prevWins[string(name)]; + } + else { + newWin = new CutWindow(this, m_disp, list[i]); + } + newWin->setName(string(name)); + m_windowList.push_back(newWin); + free(name); + } + XFree(list); +#endif + +} + +#ifdef LINUX +char* CutWindowsManager::getWinName(Display* disp, Window win) { + Atom prop = XInternAtom(disp,"WM_NAME",false); + Atom type; + int form; + unsigned long remain, len; + unsigned char *list; + + if (XGetWindowProperty(disp,win,prop,0,1024,false,XA_STRING, + &type,&form,&len,&remain,&list) != Success) { + cout<<"Error getting window name"<<endl; + return NULL; + } + return (char*)list; +} + +Window* CutWindowsManager::getWinList(Display* disp, unsigned long* len) { + Atom prop = XInternAtom(disp,"_NET_CLIENT_LIST",false); + Atom type; + int form; + unsigned long remain; + unsigned char *list; + if(XGetWindowProperty(disp,XDefaultRootWindow(disp), + prop,0,1024,false,XA_WINDOW, + &type,&form,len,&remain,&list) != Success) { + cout<<"Error getting windows list"<<endl; + return 0; + } + return (Window*)list; +} +#endif + diff --git a/src/modules/RevealedCutModule.hpp b/src/modules/RevealedCutModule.hpp new file mode 100644 index 0000000..86dafd4 --- /dev/null +++ b/src/modules/RevealedCutModule.hpp @@ -0,0 +1,160 @@ +/*************************************************************************** + * RevealedCutModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef RevealedCutModule_h +#define RevealedCutModule_h + + +#include "ShapeModule.hpp" +#include "RevealedModule.hpp" + +#include <FL/Fl_Box.H> +#include <FL/Fl_Image_Surface.H> + +#ifdef LINUX +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#endif + + +class CutWindow; +class CutWindowsManager; + +class RevealedCutModule : public ShapeModule, public RevealedModule { + public: + RevealedCutModule(); + virtual ~RevealedCutModule(); + void draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + std::map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& comp=0); + virtual void update(const int& timeDiffMs); + + static void windowCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedCutModule*>(mod)->setWindow(vals[0]); + } + void setWindow(const std::string& text); + static void refreshWindowsCallback(Module* mod) { + dynamic_cast<RevealedCutModule*>(mod)->refreshWindows(); + } + virtual void refreshWindows(); + static void selPosCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<RevealedCutModule*>(mod)->selPos(vals[0], vals[1]); + } + void selPos(const int& posX, const int& posY); + static void selSizeCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<RevealedCutModule*>(mod)->selSize(vals[0], vals[1]); + } + void selSize(const int& sizeX, const int& sizeY); + static void updateOnceCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<RevealedCutModule*>(mod)->updateOnce(vals[0]); + } + void updateOnce(bool); + void recomputePixels(); + + protected: + std::string m_text; + CutWindow* m_cutWin; + int m_winX, m_winY, m_winW, m_winH; + float* m_coordImage; + int m_nbPixPerRow; + std::vector<int> m_srcIndices; + std::vector<std::vector<int> > m_srcCoords; + std::vector<int> m_destIndices; + bool m_updateOnce; + bool m_updateOnceDone; +}; + +class CutWindow { + public: +#ifdef LINUX + CutWindow(CutWindowsManager* man, Display* disp, const Window& win); + ~CutWindow(); +#endif + int computeNbPixPerRow(const int& srcW, const int& srcH); + uchar* grabImage(); + void releaseImage(); + + void setName(const std::string& name){m_name=name;} + const std::string& getName(){return m_name;} + const int& getHeight(){return m_height;} + const int& getWidth(){return m_width;} + + private: + CutWindowsManager* m_winsMan; + int m_winID; + std::string m_name; + int m_posX, m_posY, m_width, m_height; + int m_offsetX, m_offsetY, m_pixPerRow; + uchar* m_imgData; + uchar* m_defaultImgData; + bool m_grabbed; + bool m_init; + +#ifdef LINUX + Display* m_disp; + Window m_win; + XImage* m_ximg; +#endif +}; + +class CutWindowsManager { + public: + static CutWindowsManager* getInstance(); + ~CutWindowsManager(); + void updateWindowsList(); + std::vector<CutWindow*>& editWindowList(){return m_windowList;} + CutWindow* getWindow(const std::string& name) { + CutWindow* res=NULL; + std::vector<CutWindow*>::iterator itWin=m_windowList.begin(); + for(; itWin!=m_windowList.end(); ++itWin) { + if((*itWin)->getName().compare(name)==0 && name.compare("")!=0){ + res=(*itWin); + } + } + return res; + } + int getNbWindows(){return m_windowList.size();} + + #ifdef LINUX + Window* getWinList(Display* disp, unsigned long* len); + char* getWinName(Display* disp, Window); + #endif + + private: + CutWindowsManager(); + std::vector<CutWindow*> m_windowList; + std::map<unsigned int, CutWindow*> m_windowMap; + + #ifdef LINUX + Display* m_disp; + #endif +}; + + +#endif + diff --git a/src/modules/RevealedGridModule.cpp b/src/modules/RevealedGridModule.cpp new file mode 100644 index 0000000..504ef96 --- /dev/null +++ b/src/modules/RevealedGridModule.cpp @@ -0,0 +1,202 @@ +/*************************************************************************** + * RevealedGridModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "RevealedGridModule.hpp" + +#include "../geoms/Geometry.hpp" + +#include <glm/gtx/matrix_decompose.hpp> +#include <glm/gtx/quaternion.hpp> +#include <glm/gtx/polar_coordinates.hpp> +#include <glm/gtx/rotate_vector.hpp> +#include <glm/gtx/euler_angles.hpp> + +using namespace std; + +RevealedGridModule::RevealedGridModule(): GroupModule() { + m_type="Grid"; + m_name="grid"; + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + //addVisibleFromAttribute(); //TODO + + addAttribute(new Attribute("dimensions", + Attribute::FLOAT_ATTRIBUTE, + dimensionsCallback, this, 3)); + + addTransformationAttributes(); + + addAttribute(new Attribute("elements_number", + Attribute::INT_ATTRIBUTE, + elementsNumberCallback, this, 3)); + addAttribute(new Attribute("elements_size", + Attribute::FLOAT_ATTRIBUTE, + elementsSizeCallback, this, 1)); + addAttribute(new Attribute("revealed_elements", + Attribute::FLOAT_ATTRIBUTE, + elementsRevealedCallback, this, 2)); + m_revAttributes.push_back(m_attributesMap["revealed_elements"]); + + //TODO add mode : random, aligned, personnalized + //TODO add element pos attribute : element id then pos 3D + + m_totalNbElements=0; + m_nbElements[0]=m_nbElements[1]=m_nbElements[2]=0; + m_gridDims[0]=m_gridDims[1]=m_gridDims[2]=200; + m_elementsSize=20; + m_attributesMap["elements_size"]->setFloats(vector<float>(1, 20)); + m_attributesMap["elements_number"]->setInts(vector<int>(3, 5)); + m_attributesMap["dimensions"]->setFloats(vector<float>(3, 200)); + + m_revealed.push_back(0); + m_revealed.push_back(0); +} + +RevealedGridModule::~RevealedGridModule() { +} + +void RevealedGridModule::deleteModule() { + GroupModule::deleteModule(); + for(int i=0; i<m_totalNbElements; ++i) { + m_elements[i]->deleteModule(); + } +} + +void RevealedGridModule::draw() { +} + +void RevealedGridModule::updateModelMatrix() { + GroupModule::updateModelMatrix(); + for(GridElementModule* el : m_elements) { + el->setParentMatrix(m_modelMat); + el->updateModelMatrix(); + } +} + +void RevealedGridModule::setVisible(bool vis) { + GroupModule::setVisible(vis); + for(int i=0; i<m_totalNbElements && i<int(m_elements.size()); ++i) { + m_elements[i]->setParentVisible(m_parentVisible&&m_visible); + } +} + +void RevealedGridModule::setGridDimensions(const float& x, + const float& y, + const float& z) { + if(x>0 && y>0 && z>0) { + m_gridDims[0]=x; + m_gridDims[1]=y; + m_gridDims[2]=z; + updateGridPoints(); + } +} + +void RevealedGridModule::setElementsNumber(const int& x, + const int& y, + const int& z) { + int nb = x*y*z; + if(nb>0) { + m_nbElements[0]=x; + m_nbElements[1]=y; + m_nbElements[2]=z; + if(nb>m_totalNbElements) { + for(int i=m_totalNbElements; i<nb; ++i) { + m_elements.push_back(new GridElementModule(m_elements.size(), + this)); + } + } + m_totalNbElements=nb; + for(int i=0; i<m_totalNbElements; ++i) { + m_elements[i]->setVisible(true); + } + for(unsigned int i=m_totalNbElements; i<m_elements.size(); ++i) { + m_elements[i]->setVisible(false); + } + updateGridPoints(); + } +} + +void RevealedGridModule::setElementsSize(const float& s) { + if(s>0) { + m_elementsSize=s; + updateGridPoints(); + } +} + +void RevealedGridModule::update(const int& timeDiffMs) { +} + +void RevealedGridModule::updateModulesList(const map<string, Module*>& mods) { +} + +void RevealedGridModule::updateGridPoints() { + int el=0; + vector<float> pos(3,0); + float steps[3]; + for(int i=0; i<3; ++i) { + steps[i]=m_gridDims[i]/m_nbElements[i]; + } + vector<float> dims(3, m_elementsSize); + for(int x=0; x<m_nbElements[0]; x++) { + for(int y=0; y<m_nbElements[1]; y++) { + for(int z=0; z<m_nbElements[2]; z++) { + pos[0]=(x-m_nbElements[0]/2.0+0.5)*steps[0]; + pos[1]=(y-m_nbElements[1]/2.0+0.5)*steps[1]; + pos[2]=(z-m_nbElements[2]/2.0+0.5)*steps[2]; + m_elements[el]->getAttribute("position")->setFloats(pos); + m_elements[el]->getAttribute("dimensions")->setFloats(dims); + el++; + } + } + } + updateModelMatrix(); +} + +void RevealedGridModule::gotAttributeListenersUpdate(Attribute* att) { + bool active=false; + for(Attribute *att : m_revAttributes) { + if(att->editListeners().size()>0) { + active=true; + } + } + if(active) { + for(GridElementModule* el : m_elements) { + Reveal::getInstance()->registerOutputRevealed(el); + } + } + else { + vector<GridElementModule*>::iterator el=m_elements.begin(); + for(; el!=m_elements.end(); el++) { + Reveal::getInstance()->unregisterOutputRevealed(*el); + } + } +} + +void RevealedGridModule::processRevealedElement(const int& elID, + const float& val) { + m_revealed[0]=elID; + m_revealed[1]=val; + m_attributesMap["revealed_elements"]->setFloatsIfChanged(m_revealed); +} + diff --git a/src/modules/RevealedGridModule.hpp b/src/modules/RevealedGridModule.hpp new file mode 100644 index 0000000..0781325 --- /dev/null +++ b/src/modules/RevealedGridModule.hpp @@ -0,0 +1,126 @@ +/*************************************************************************** + * RevealedGridModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef RevealedGridModule_h +#define RevealedGridModule_h + +#include "GroupModule.hpp" +#include "RevealedShapeModule.hpp" + +class GridElementModule; + +class RevealedGridModule : public GroupModule, + public ModuleListObserver { + public: + RevealedGridModule(); + virtual ~RevealedGridModule(); + virtual void deleteModule(); + + void draw(); + void setVisible(bool vis); + + static void dimensionsCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedGridModule*>(mod)->setGridDimensions(vals[0], + vals[1], + vals[2]); + } + void setGridDimensions(const float& x, + const float& y, + const float& z); + + static void elementsNumberCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<RevealedGridModule*>(mod)->setElementsNumber(vals[0], + vals[1], + vals[2]); + } + void setElementsNumber(const int& x, + const int& y, + const int& z); + + + static void elementsSizeCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedGridModule*>(mod)->setElementsSize(vals[0]); + } + void setElementsSize(const float& th); + + static void elementsRevealedCallback(Module* mod, + const std::vector<float>& vals) {} + void processRevealedElement(const int&, const float&); + + + void update(const int& timeDiffMs); + virtual void updateModulesList(const std::map<std::string, Module*>&); + + void gotAttributeListenersUpdate(Attribute* att); + void updateGridPoints(); + + virtual void updateModelMatrix(); + + protected: + int m_totalNbElements; + int m_nbElements[3]; + float m_gridDims[3]; + std::vector<GridElementModule*> m_elements; + std::vector<float> m_positions; + float m_elementsSize; + std::vector<Attribute*> m_revAttributes; + std::vector<float> m_revealed; + bool m_revealedChanged; +}; + +class GridElementModule : public RevealedShapeModule { + public: + GridElementModule(const int& elID, + RevealedGridModule* arr) : RevealedShapeModule(), + m_elementID(elID), + m_grid(arr), + m_revealed(0) { + } + + virtual void processReveal(const unsigned int& id, + const std::vector<std::string>& name, + const std::vector<float>& surface, + const std::vector<float>& inside, + const std::vector<float>& center, + const std::vector<float>& extent, + const std::vector<float>& color, + const std::vector<float>& blob) { + + if(m_revealed!=(inside[0]+surface[0]>0)?1:0) { + m_revealed=(inside[0]+surface[0]>0)?1:0; + m_grid->processRevealedElement(m_elementID, m_revealed); + } + } + + private: + int m_elementID; + int m_elementRevealed; + RevealedGridModule* m_grid; + float m_revealed; +}; + +#endif + diff --git a/src/modules/RevealedModelModule.cpp b/src/modules/RevealedModelModule.cpp new file mode 100644 index 0000000..9369cf0 --- /dev/null +++ b/src/modules/RevealedModelModule.cpp @@ -0,0 +1,114 @@ +/*************************************************************************** + * RevealedModelModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "RevealedModelModule.hpp" + +#include "../geoms/Geometry.hpp" + +#include <math.h> +#define EPSILON 0.0001 + +using namespace std; + +RevealedModelModule::RevealedModelModule(): ModelModule(), RevealedModule(){ + m_type="Model"; + m_name="model"; + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + addVisibleFromAttribute(); + addRevealedByAttribute(); + addModelAttributes(); + addTransformationAttributes(); + addFollowMarkerAttribute(); + addRevealedAttributes(); + + addRevealedInsideStructureAttributes(); + + addAttribute(new Attribute("generate_texture_from_surface", + Attribute::ACTION_ATTRIBUTE, + generateSurfaceDistanceCallback, this, + Attribute::LOCAL)); + + addRevealedInsideGradientAttributes(); + addRevealedInsideDensityAttributes(); + addRevealedInsideTextureAttributes(); + + addRevealedOutputAttributes(); + m_currentGeom = m_modelGeom; + m_shapeGeom = Reveal::GEOM_MODEL; +} + +RevealedModelModule::~RevealedModelModule() { +/* + Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentModel]) + ->unregisterModule(this); +*/ +} + +void RevealedModelModule::draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& comp) { + + RevealedModule::draw(contextID, prog, uniforms, comp); + if(prog==Reveal::RENDERPROG) { + //send the surface distance texture + glUniform1i(uniforms[Reveal::SURFDISTEX], 5); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_3D, m_coordsIDMap[contextID]); + if(m_coordsUpMap[contextID]) { + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, + m_surfDistDims.x, m_surfDistDims.y, m_surfDistDims.z, + 0, GL_RED, GL_FLOAT, m_surfDistData.data()); + m_coordsUpMap[contextID]=false; + cout<<"update surfdist txture"<<endl; + } + } +} + +void RevealedModelModule::setModel(const std::string& fileName) { + ModelModule::setModel(fileName); + //try opening texture from surface + if(!m_modelStr.empty()) { + openSurfaceDistanceTexture(m_modelStr+"_surfdist.pvm"); + } + //ask for reinitializing texture uniform + map<int, bool>::iterator itUp = m_coordsUpMap.begin(); + for(; itUp!=m_coordsUpMap.end(); ++itUp) { + itUp->second=true; + } +} + + +void RevealedModelModule::generateSurfaceDistanceTexture() { + if(!m_modelStr.empty()) { + RevealedModule::generateSurfaceDistanceTexture(m_modelStr + + "_surfdist.pvm"); + } +} + + diff --git a/src/modules/RevealedModelModule.hpp b/src/modules/RevealedModelModule.hpp new file mode 100644 index 0000000..8370993 --- /dev/null +++ b/src/modules/RevealedModelModule.hpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * RevealedModelModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef RevealedModelModule_h +#define RevealedModelModule_h + +#include "ModelModule.hpp" +#include "RevealedModule.hpp" + +class RevealedModelModule : public ModelModule, public RevealedModule { + public: + RevealedModelModule(); + virtual ~RevealedModelModule(); + void draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + std::map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& comp=0); + void gotAttributeListenersUpdate(Attribute* att) { + RevealedModule::gotAttributeListenersUpdate(att); + } + + static void generateSurfaceDistanceCallback(Module* mod) { + dynamic_cast<RevealedModelModule*>(mod) + ->generateSurfaceDistanceTexture(); + } + void generateSurfaceDistanceTexture(); + void setModel(const std::string& fileName); + + protected: +}; + + +#endif + diff --git a/src/modules/RevealedModule.cpp b/src/modules/RevealedModule.cpp new file mode 100644 index 0000000..6c69f44 --- /dev/null +++ b/src/modules/RevealedModule.cpp @@ -0,0 +1,1797 @@ +/*************************************************************************** + * RevealedModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "RevealedModule.hpp" + +#include <iostream> +#include <fstream> +#include <limits> +#include <unistd.h> + +#include <glm/gtx/norm.hpp> + +#include <FL/filename.H> +#include <opencv2/opencv.hpp> + +#include "../geoms/Geometry.hpp" + +using namespace std; + +RevealedModule::RevealedModule(): GeomModule(), + m_volumeTextureWidth(300), + m_volumeTextureHeight(300), + m_outputActive(true) { + + Reveal::getInstance()->registerRevealed(this); + + //Material + m_surface=1; + m_reactivityType=0; + m_surfaceThickness=5.0; + m_shapeGeom=Reveal::GEOM_SPHERE; + m_layersData=NULL; + m_insideImage=NULL; + m_surfaceImage=NULL; + m_gradientImage=NULL; + m_textureGrayscale=false; + m_textureCanDelete=true; + m_layersNb=0; + for(int d=0; d<3; d++) { + m_textureOffset[d]=0; + m_textureScale[d]=1; + } + + m_revSize=0; + m_revSurf=0; + m_revIns=0; + m_revCent=0; + m_revCol=0; + m_revHis=0; + m_revVox=0; + m_voxDim=5; + m_voxSize = m_voxDim*m_voxDim*m_voxDim; + + m_outHistoSize=m_voxDim*m_voxDim; + m_outVoxelSize=m_voxDim*m_voxDim; + + m_reactThread=NULL; + m_reactTexInput = new float[m_voxSize]; + m_reactTexInternal = new float[m_voxSize]; + m_reactTexOutput = new char[m_voxSize*3]; + for(int v=0; v<m_voxSize; v++) { + m_reactTexInput[v]=0; + m_reactTexInternal[v]=0; + m_reactTexOutput[v*3]=0; + m_reactTexOutput[v*3+1]=0; + m_reactTexOutput[v*3+2]=0; + } +} + +RevealedModule::~RevealedModule() {} + +void RevealedModule::addRevealedAttributes() { + addAttribute(new Attribute("color", + Attribute::FLOAT_ATTRIBUTE, + colorCallback, this, 3)); + addAttribute(new Attribute("surface", + Attribute::STRING_ATTRIBUTE, + surfaceCallback, this, 1)); + m_surfaces.push_back("none"); + m_surfaces.push_back("color"); + m_surfaces.push_back("texture"); + m_attributesMap["surface"]->editStringValuesChoices().assign(1,m_surfaces); + m_attributesMap["surface"]->initStrings(vector<string>(1,m_surfaces[1])); + addAttribute(new Attribute("surface_color", + Attribute::FLOAT_ATTRIBUTE, + surfaceColorCallback, this, 3)); + addAttribute(new Attribute("surface_thickness", + Attribute::FLOAT_ATTRIBUTE, + surfaceThicknessCallback, this, 1)); + m_attributesMap["surface_thickness"] + ->initFloats(vector<float>(1,m_surfaceThickness)); + addAttribute(new Attribute("surface_texture", + Attribute::FILE_OPEN_ATTRIBUTE, + surfaceTextureCallback, this)); + + vector<float> initCol(3,0); + initCol[0]=360; + initCol[2]=100; + m_color.resize(3, 0); + m_surfaceColor.resize(3, 0); + hsv2rgb(initCol, m_color); + hsv2rgb(initCol, m_surfaceColor); + m_attributesMap["color"]->setFloats(initCol); + m_attributesMap["surface_color"]->setFloats(initCol); + +} + +void RevealedModule::addRevealedInsideAttributes() { + addRevealedInsideStructureAttributes(); + addRevealedInsideGradientAttributes(); + addRevealedInsideDensityAttributes(); + addRevealedInsideTextureAttributes(); +} + +void RevealedModule::addRevealedInsideStructureAttributes() { + //Visible + addAttribute(new Attribute("inside_visible", + Attribute::BOOL_ATTRIBUTE, + insideVisibleCallback, this, 1)); + m_attributesMap["inside_visible"]->initBools(vector<bool>(1, true)); + m_insideVisible=true; + + //Axes and structure + addAttribute(new Attribute("inside_axes", + Attribute::STRING_ATTRIBUTE, + insideAxesCallback, this, 1)); + m_insideAxes.push_back("local"); + m_insideAxes.push_back("global"); + m_attributesMap["inside_axes"] + ->editStringValuesChoices().assign(1, m_insideAxes); + m_attributesMap["inside_axes"] + ->initStrings(vector<string>(1, m_insideAxes[0])); + + addAttribute(new Attribute("inside_structure", + Attribute::STRING_ATTRIBUTE, + insideStructureCallback, this, 1)); + m_insideStructures.push_back("from_center"); + m_insideStructures.push_back("along_x"); + m_insideStructures.push_back("along_y"); + m_insideStructures.push_back("along_z"); + m_insideStructures.push_back("from_surface"); + m_attributesMap["inside_structure"] + ->editStringValuesChoices().assign(1, m_insideStructures); + m_attributesMap["inside_structure"] + ->setStrings(vector<string>(1,m_insideStructures[4])); + + m_structureRatio=0; + addAttribute(new Attribute("structure_ratio", + Attribute::FLOAT_ATTRIBUTE, + structureRatioCallback, this, 1)); +} + +void RevealedModule::addRevealedInsideGradientAttributes() { + //Gradient + addAttribute(new Attribute("gradient_alpha", + Attribute::FLOAT_ATTRIBUTE, + gradientAlphaCallback, this, 1)); + m_attributesMap["gradient_alpha"]->setFloats(vector<float>(1, 1)); + addAttribute(new Attribute("gradient_type", + Attribute::STRING_ATTRIBUTE, + gradientTypeCallback, this, 1)); + m_gradientTypes.push_back("grayscale"); + m_gradientTypes.push_back("texture"); + m_attributesMap["gradient_type"] + ->editStringValuesChoices().assign(1, m_gradientTypes); + m_attributesMap["gradient_type"] + ->setStrings(vector<string>(1, m_gradientTypes[0])); + addAttribute(new Attribute("gradient_steps", + Attribute::INT_ATTRIBUTE, + gradientStepsCallback, this, 1)); + addAttribute(new Attribute("gradient_curve_ratio", + Attribute::FLOAT_ATTRIBUTE, + gradientCurveRatioCallback, this, 1)); + m_attributesMap["gradient_curve_ratio"]->setFloats(vector<float>(1, 1.0)); + + addAttribute(new Attribute("gradient_texture", + Attribute::FILE_OPEN_ATTRIBUTE, + gradientTextureCallback, this)); +} + +void RevealedModule::addRevealedInsideDensityAttributes() { + //Density + addAttribute(new Attribute("density_alpha", + Attribute::FLOAT_ATTRIBUTE, + densityAlphaCallback, this, 1)); + m_attributesMap["density_alpha"]->setFloats(vector<float>(1, 0.5)); + addAttribute(new Attribute("density_type", + Attribute::STRING_ATTRIBUTE, + densityTypeCallback, this, 1)); + m_insideDensityTypes.push_back("layers"); + m_insideDensityTypes.push_back("grid"); + m_insideDensityTypes.push_back("pointcloud"); + m_attributesMap["density_type"] + ->editStringValuesChoices().assign(1, m_insideDensityTypes); + m_attributesMap["density_type"] + ->setStrings(vector<string>(1,m_insideDensityTypes[0])); + addAttribute(new Attribute("density_ratio", + Attribute::FLOAT_ATTRIBUTE, + densityRatioCallback, this, 1)); + m_attributesMap["density_ratio"]->setFloats(vector<float>(1,0.3)); + addAttribute(new Attribute("density_size", + Attribute::FLOAT_ATTRIBUTE, + densitySizeCallback, this, 1)); + m_attributesMap["density_size"]->setFloats(vector<float>(1,0.1)); + addAttribute(new Attribute("density_curve_ratio", + Attribute::FLOAT_ATTRIBUTE, + densityCurveRatioCallback, this, 1)); + m_attributesMap["density_curve_ratio"]->setFloats(vector<float>(1,1)); +} + +void RevealedModule::addRevealedInsideTextureAttributes() { + //Textures + addAttribute(new Attribute("texture_alpha", + Attribute::FLOAT_ATTRIBUTE, + textureAlphaCallback, this, 1)); + addAttribute(new Attribute("texture", + Attribute::FILE_OPEN_ATTRIBUTE, + textureCallback, this)); + addAttribute(new Attribute("texture_layers_folder", + Attribute::FOLDER_OPEN_ATTRIBUTE, + textureLayersFolderCallback, this)); + addAttribute(new Attribute("texture_grayscale", + Attribute::BOOL_ATTRIBUTE, + textureGrayscaleCallback, this, 1)); + addAttribute(new Attribute("texture_blend", + Attribute::BOOL_ATTRIBUTE, + textureBlendCallback, this, 1)); + m_attributesMap["texture_blend"]->setBools(vector<bool>(1, true)); + addAttribute(new Attribute("texture_offset", + Attribute::FLOAT_ATTRIBUTE, + textureOffsetCallback, this, 3)); + addAttribute(new Attribute("texture_scale", + Attribute::FLOAT_ATTRIBUTE, + textureScaleCallback, this, 3)); + m_attributesMap["texture_scale"]->initFloats(vector<float>(3, 1)); + + addAttribute(new Attribute("texture_reactivity", + Attribute::STRING_ATTRIBUTE, + textureReactCallback, this, 1)); + m_reactivityTypes.push_back("none"); + m_reactivityTypes.push_back("thermal"); + m_attributesMap["texture_reactivity"] + ->editStringValuesChoices().assign(1, m_reactivityTypes); + m_attributesMap["texture_reactivity"] + ->initStrings(vector<string>(1,m_reactivityTypes[0])); + + addAttribute(new Attribute("layer_anim_position", + Attribute::FLOAT_ATTRIBUTE, + animPosCallback, this, 1)); + addAttribute(new Attribute("layer_anim_play", + Attribute::BOOL_ATTRIBUTE, + animPlayCallback, this, 1)); + m_attributesMap["layer_anim_play"]->initBools(vector<bool>(1,false)); + addAttribute(new Attribute("layer_anim_speed", + Attribute::FLOAT_ATTRIBUTE, + animSpeedCallback, this, 1)); + m_attributesMap["layer_anim_speed"]->initFloats(vector<float>(1,1)); +} + +void RevealedModule::addRevealedOutputAttributes() { + addAttribute(new Attribute("revealed_name", + Attribute::STRING_ATTRIBUTE, + revnamCallback, this, 1, Attribute::OUTPUT)); + m_attributesMap["revealed_name"]->initStrings(vector<string>(1,"name")); + m_revAttributes.push_back(m_attributesMap["revealed_name"]); + addAttribute(new Attribute("revealed_surface", + Attribute::FLOAT_ATTRIBUTE, + revsurCallback, this, 1, Attribute::OUTPUT)); + m_revAttributes.push_back(m_attributesMap["revealed_surface"]); + m_attributesMap["revealed_surface"]->setChangeCount(30); + addAttribute(new Attribute("revealed_inside", + Attribute::FLOAT_ATTRIBUTE, + revinsCallback, this, 1, Attribute::OUTPUT)); + m_attributesMap["revealed_inside"]->setChangeCount(30); + m_revAttributes.push_back(m_attributesMap["revealed_inside"]); + addAttribute(new Attribute("revealed_center", + Attribute::FLOAT_ATTRIBUTE, + revcentCallback, this, 3, Attribute::OUTPUT)); + m_revAttributes.push_back(m_attributesMap["revealed_center"]); + addAttribute(new Attribute("revealed_extent", + Attribute::FLOAT_ATTRIBUTE, + revextCallback, this, 4, Attribute::OUTPUT)); + m_revAttributes.push_back(m_attributesMap["revealed_extent"]); + addAttribute(new Attribute("revealed_color", + Attribute::FLOAT_ATTRIBUTE, + revcolCallback, this, 3, Attribute::OUTPUT)); + m_revAttributes.push_back(m_attributesMap["revealed_color"]); + addAttribute(new Attribute("revealed_histo", + Attribute::FLOAT_ATTRIBUTE, + revhistoCallback, this, m_outHistoSize, + Attribute::OUTPUT)); + m_revAttributes.push_back(m_attributesMap["revealed_histo"]); + addAttribute(new Attribute("revealed_voxels", + Attribute::FLOAT_ATTRIBUTE, + revvoxelCallback, this, + m_outVoxelSize*4, + Attribute::OUTPUT)); + m_revAttributes.push_back(m_attributesMap["revealed_voxels"]); +} + +void RevealedModule::deleteModule() { + Reveal::getInstance()->unregisterRevealed(this); + GeomModule::deleteModule(); +} + +void RevealedModule::draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& comp){ + + GeomModule::draw(contextID, prog, uniforms, comp); + glUniform3fv(uniforms[Reveal::SHAPECOLOR], 1, &m_color[0]); + + glUniform1i(uniforms[Reveal::SURFACE], m_surface); + glUniform3fv(uniforms[Reveal::SURFACECOLOR], 1, &m_surfaceColor[0]); + glUniform1f(uniforms[Reveal::SURFACETHICKNESS], m_surfaceThickness); + + glUniform1f(uniforms[Reveal::SHAPEID], m_revID); + glUniform1f(uniforms[Reveal::SHAPEIDBIT], m_revIDBit); + glUniform1i(uniforms[Reveal::SHAPEGEOM], m_shapeGeom); + if(prog==Reveal::RENDERPROG) { + if(m_insideIDMap.find(contextID)==m_insideIDMap.end()) { + GLuint texID; + glGenTextures(1, &texID); + m_insideIDMap[contextID]=texID; + m_insideUpMap[contextID]=true; + + glGenTextures(1, &texID); + m_coordsIDMap[contextID]=texID; + m_coordsUpMap[contextID]=true; + + glGenTextures(1, &texID); + m_surfaceIDMap[contextID]=texID; + m_surfaceUpMap[contextID]=true; + + glGenTextures(1, &texID); + m_gradientIDMap[contextID]=texID; + m_gradientUpMap[contextID]=true; + + m_boundingRect[contextID]=glm::vec4(0.0); + m_boundingRectUpdate[contextID]=true; + + glGenTextures(1, &texID); + m_reactIDMap[contextID]=texID; + m_reactUpMap[contextID]=true; + } + + //test if bounding rect needs updating + if(m_boundingRectUpdate[contextID]) { + //get viewproj matrix of current projector + ContextHandler* proj = Reveal::getInstance() + ->getContextHandler(contextID); + glm::mat4& mat = proj->getViewProjMat(); + + m_boundingRect[contextID][0]=numeric_limits<float>::max(); + m_boundingRect[contextID][1]=numeric_limits<float>::max(); + m_boundingRect[contextID][2]=-numeric_limits<float>::max(); + m_boundingRect[contextID][3]=-numeric_limits<float>::max(); + for(int p=0; p<8; ++p) { + glm::vec4 pnt; + pnt[0] = m_bbPnts[p%2][0]; + pnt[1] = m_bbPnts[(p/2)%2][1]; + pnt[2] = m_bbPnts[(p/4)%2][2]; + pnt[3] = 1.0; + + //transform the point with viewproj matrix + pnt = mat * pnt; + + //find the bounding rect + m_boundingRect[contextID][0] + = min<float>(pnt[0]/pnt[3], m_boundingRect[contextID][0]); + m_boundingRect[contextID][1] + = min<float>(pnt[1]/pnt[3], m_boundingRect[contextID][1]); + m_boundingRect[contextID][2] + = max<float>(pnt[0]/pnt[3], m_boundingRect[contextID][2]); + m_boundingRect[contextID][3] + = max<float>(pnt[1]/pnt[3], m_boundingRect[contextID][3]); + } + + //put coordinates between 0 and 1 + for(int p=0; p<4; ++p) { + m_boundingRect[contextID][p] + = (m_boundingRect[contextID][p]+1.0)/2.0; + } + + m_boundingRect[contextID][0]=1.0-m_boundingRect[contextID][0]; + m_boundingRect[contextID][2]=1.0-m_boundingRect[contextID][2]; + + m_boundingRectUpdate[contextID]=false; + } + + glUniform1i(uniforms[Reveal::REVSIZE], m_revSize); + glUniform1i(uniforms[Reveal::REVSURFACE], m_revSurf); + glUniform1i(uniforms[Reveal::REVINSIDE], m_revIns); + glUniform1i(uniforms[Reveal::REVCENTER], m_revCent); + glUniform1i(uniforms[Reveal::REVCOLOR], m_revCol); + glUniform1i(uniforms[Reveal::REVHISTO], m_revHis); + glUniform1i(uniforms[Reveal::REVVOXELS], m_revVox); + glUniform1i(uniforms[Reveal::OUTHISTOSIZE], m_outHistoSize); + glUniform1i(uniforms[Reveal::OUTVOXELSIZE], m_voxDim); + glUniform4fv(uniforms[Reveal::BRECT], 1, &m_boundingRect[contextID][0]); + glUniform1i(uniforms[Reveal::REVEALEDBY], m_revealedBy); + glUniform1i(uniforms[Reveal::REACTIVITY], m_reactivityType); + + glUniform1i(uniforms[Reveal::INSIDEVISIBLE], m_insideVisible); + glUniform1i(uniforms[Reveal::INSIDESTRUCT], m_insideStructure); + glUniform1f(uniforms[Reveal::STRUCTRATIO], m_structureRatio); + + glUniform1f(uniforms[Reveal::GRADIENTALPHA], m_insideGradientAlpha); + glUniform1i(uniforms[Reveal::GRADIENTTYPE], m_gradientType); + glUniform1i(uniforms[Reveal::GRADIENTSTEPS], m_insideGradientSteps); + glUniform1f(uniforms[Reveal::GRADIENTCURVERATIO], + m_insideGradientCurveRatio); + + glUniform1f(uniforms[Reveal::DENSITYALPHA], m_insideDensityAlpha); + glUniform1i(uniforms[Reveal::DENSITYTYPE], m_insideDensityType); + glUniform1f(uniforms[Reveal::DENSITYRATIO], m_insideDensityRatio); + glUniform1f(uniforms[Reveal::DENSITYSIZE], m_insideDensitySize); + glUniform1f(uniforms[Reveal::DENSITYCURVERATIO], + m_insideDensityCurveRatio); + + glUniform1f(uniforms[Reveal::TEXALPHA], m_insideTextureAlpha); + glUniform1i(uniforms[Reveal::TEXBLEND], m_insideTextureBlend); + glUniform3fv(uniforms[Reveal::TEXOFFSET], 1, &m_textureOffset[0]); + glUniform3fv(uniforms[Reveal::TEXSCALE], 1, &m_textureScale[0]); + glUniform1i(uniforms[Reveal::TEXGRAY], m_textureGrayscale); + + glUniform1i(uniforms[Reveal::INSIDETEX], 2); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_3D, m_insideIDMap[contextID]); + + //test layers update + int d=0; + vector<RevealedLayer*>::iterator itLa = m_layers.begin(); + for(; itLa!=m_layers.end(); ++itLa, ++d) { + if((*itLa)->update(m_timeDiffMs, d, m_layersData, + m_texWidth, m_texHeight)) { + m_insideUpMap[contextID]=true; + } + } + + if(m_insideUpMap[contextID]) { + if(m_insideTextureBlend) { + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + } + else { + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + } + if(m_layersNb>0) { + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, + m_texWidth, m_texHeight, m_layersNb, 0, + GL_RGB, GL_UNSIGNED_BYTE, + m_layersData); + } + else if(m_insideImage) { + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, + m_texWidth, m_texHeight, 1, 0, + (m_insideImage->d()>3)?GL_RGBA:GL_RGB, + GL_UNSIGNED_BYTE, + m_insideImage->data()[0]); + } + m_insideUpMap[contextID]=false; + } + + glUniform1i(uniforms[Reveal::GRADIENTTEXTURE], 6); + glActiveTexture(GL_TEXTURE6); + glBindTexture(GL_TEXTURE_2D, m_gradientIDMap[contextID]); + if(m_gradientUpMap[contextID] && m_gradientImage) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, + m_texWidth, m_texHeight, 0, + GL_RGB, GL_UNSIGNED_BYTE, + m_gradientImage->data()[0]); + m_gradientUpMap[contextID]=false; + } + + glUniform1i(uniforms[Reveal::SURFACETEX], 3); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, m_surfaceIDMap[contextID]); + if(m_surfaceUpMap[contextID] && m_surfaceImage) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, + m_texWidth, m_texHeight, 0, + GL_RGB, GL_UNSIGNED_BYTE, + m_surfaceImage->data()[0]); + m_surfaceUpMap[contextID]=false; + } + + glUniform1i(uniforms[Reveal::REACTTEX], 4); + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_3D, m_reactIDMap[contextID]); + if(m_reactUpMap[contextID] && m_reactLock.try_lock()) { + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, + m_voxDim, m_voxDim, m_voxDim, 0, + GL_RGB, GL_UNSIGNED_BYTE, + m_reactTexOutput); + m_reactUpMap[contextID]=false; + m_reactLock.unlock(); + } + } +} + +void RevealedModule::update(const int& timeDiffMs) { + m_timeDiffMs=timeDiffMs; +} + +void RevealedModule::setColor(const vector<float>& hsv) { + hsv2rgb(hsv, m_color); +} + +/* +void RevealedModule::setInside(const std::string& inside) { + int ins=0; + vector<string>::iterator itIns=m_insides.begin(); + for(; itIns!=m_insides.end(); ++itIns, ++ins) { + if((*itIns).compare(inside)==0) { + m_inside=ins; + } + } + map<int, bool>::iterator itUp = m_insideUpMap.begin(); + for(; itUp!=m_insideUpMap.end(); ++itUp) { + itUp->second=true; + } +}*/ + +void RevealedModule::setInsideAxes(const std::string& axes) { + if(axes.compare("local")==0) { + m_localInsideAxes = true; + } + else { + m_localInsideAxes = false; + } + updateModelMatrix(); +} + +void RevealedModule::setInsideStructure(const std::string& stru) { + int t=0; + vector<string>::iterator itStruct=m_insideStructures.begin(); + for(; itStruct!=m_insideStructures.end(); ++itStruct, ++t) { + if((*itStruct).compare(stru)==0) { + m_insideStructure = t; + } + } +} + +void RevealedModule::setTextureBlend(bool b){ + m_insideTextureBlend=b; + map<int, bool>::iterator itUp = m_insideUpMap.begin(); + for(; itUp!=m_insideUpMap.end(); ++itUp) { + itUp->second=true; + } +} + +void RevealedModule::generateSurfaceDistanceTexture(const std::string& file) { + ostringstream os; + //int maxDigits = os.str().length(); + + vector<GLfloat>& vertices = m_currentGeom->editVertexBufferData(); + vector<GLuint>& indices = m_currentGeom->editIndexBufferData(); + + cout<<"Building volumetric texture from "<<indices.size()/3<<" faces" + <<" and saving to file "<<file<<endl; + + //m_surfDistDims = glm::vec3(64,64,64); + m_surfDistDims = glm::ivec3(128,128,128); + + //voxels + std::vector<float> voxels(m_surfDistDims.x + *m_surfDistDims.y + *m_surfDistDims.z, 0); + + //for each pixel in the volumetric texture + for(int v = 0; v < int(voxels.size()); ++v) { + cout<<"Computing surface distance " + <<to_string(float(v)/float(voxels.size())*100.0)<<"%"<<endl; + + //get 3D coord + int i=v%m_surfDistDims.x; + int j=(v/m_surfDistDims.x)%m_surfDistDims.y; + int k=v/(m_surfDistDims.x*m_surfDistDims.y); + + //get 3D pos of voxel + glm::vec3 pos; + glm::vec3 pixCol(0,0,0); + + pos[0] = (1.0-float(i)/float(m_surfDistDims.x))-0.5; + pos[1] = (1.0-float(j)/float(m_surfDistDims.y))-0.5; + pos[2] = (float(k)/float(m_surfDistDims.z))-0.5; + + //find closest face + float minDist = std::numeric_limits<float>::max(); + glm::vec3 nearestPnt; + + for(unsigned int f=0; f<indices.size()/3; f++) { + + glm::vec3 v0(vertices[indices[f*3+0]*5], + vertices[indices[f*3+0]*5+1], + vertices[indices[f*3+0]*5+2]); + glm::vec3 v1(vertices[indices[f*3+1]*5], + vertices[indices[f*3+1]*5+1], + vertices[indices[f*3+1]*5+2]); + glm::vec3 v2(vertices[indices[f*3+2]*5], + vertices[indices[f*3+2]*5+1], + vertices[indices[f*3+2]*5+2]); + + auto diff = v0 - pos; + auto edge0 = v1 - v0; + auto edge1 = v2 - v0; + auto a00 = glm::dot(edge0, edge0); + auto a01 = glm::dot(edge0, edge1); + auto a11 = glm::dot(edge1, edge1); + auto b0 = glm::dot(diff,edge0); + auto b1 = glm::dot(diff,edge1); + auto det = std::abs(a00 * a11 - a01 * a01); + auto s = a01 * b1 - a11 * b0; + auto t = a01 * b0 - a00 * b1; + + //NearestTriEntity ne; + if (s + t <= det) { + if (s < 0) { + if (t < 0) { // region 4 + if (b0 < 0) { + t = 0; + if (-b0 >= a00) { + // VN1 + //ne = NearestTriEntity::Vert1; + s = 1; + } + else { + // EN0 + //ne = NearestTriEntity::Edge0; + s = -b0 / a00; + } + } + else { + s = 0; + + if (b1 >= 0) { + // VN0 + //ne = NearestTriEntity::Vert0; + t = 0; + } + else if (-b1 >= a11) { + // VN2 + //ne = NearestTriEntity::Vert2; + t = 1; + } + else { + // EN2 + //ne = NearestTriEntity::Edge2; + t = -b1 / a11; + } + } + } + else { // region 3 + s = 0; + + if (b1 >= 0) { + // VN0 + //ne = NearestTriEntity::Vert0; + t = 0; + } + else if (-b1 >= a11) { + // VN2 + //ne = NearestTriEntity::Vert2; + t = 1; + } + else { + // EN2 + //ne = NearestTriEntity::Edge2; + t = -b1 / a11; + } + } + } + else if (t < 0) { // region 5 + t = 0; + + if (b0 >= 0) { + // VN0 + //ne = NearestTriEntity::Vert0; + s = 0; + } + else if (-b0 >= a00) { + // VN1 + //ne = NearestTriEntity::Vert1; + s = 1; + } + else { + // EN0 + //ne = NearestTriEntity::Edge0; + s = -b0 / a00; + } + } + else { // region 0 + // FN + //ne = NearestTriEntity::Face; + // minimum at interior point + auto invDet = (1) / det; + s *= invDet; + t *= invDet; + } + } + else { + double tmp0, tmp1, numer, denom; + + if (s < 0) { // region 2 + tmp0 = a01 + b0; + tmp1 = a11 + b1; + + if (tmp1 > tmp0) { + numer = tmp1 - tmp0; + denom = a00 - (2) * a01 + a11; + + if (numer >= denom) { + // VN1 + //ne = NearestTriEntity::Vert1; + s = 1; + t = 0; + } + else { + // EN1 + //ne = NearestTriEntity::Edge1; + s = numer / denom; + t = 1 - s; + } + } + else { + s = 0; + + if (tmp1 <= 0) { + // VN2 + //ne = NearestTriEntity::Vert2; + t = 1; + } + else if (b1 >= 0) { + // VN0 + //ne = NearestTriEntity::Vert0; + t = 0; + } + else { + // EN2 + //ne = NearestTriEntity::Edge2; + t = -b1 / a11; + } + } + } + else if (t < 0) { // region 6 + tmp0 = a01 + b1; + tmp1 = a00 + b0; + + if (tmp1 > tmp0) { + numer = tmp1 - tmp0; + denom = a00 - 2 * a01 + a11; + + if (numer >= denom) { + // VN2 + //ne = NearestTriEntity::Vert2; + t = 1; + s = 0; + } + else { + // EN1 + //ne = NearestTriEntity::Edge1; + t = numer / denom; + s = 1 - t; + } + } + else { + t = 0; + + if (tmp1 <= 0) { + // VN1 + //ne = NearestTriEntity::Vert1; + s = 1; + } + else if (b0 >= 0) { + // VN0 + //ne = NearestTriEntity::Vert0; + s = 0; + } + else { + // EN0 + //ne = NearestTriEntity::Edge0; + s = -b0 / a00; + } + } + } + else { // region 1 + numer = a11 + b1 - a01 - b0; + + if (numer <= 0) { + // VN2 + //ne = NearestTriEntity::Vert2; + s = 0; + t = 1; + } + else { + denom = a00 - (2) * a01 + a11; + if (numer >= denom) { + // VN1 + //ne = NearestTriEntity::Vert1; + s = 1; + t = 0; + } + else { + // EN1 + //ne = NearestTriEntity::Edge1; + s = numer / denom; + t = 1 - s; + } + } + } + } + + glm::vec3 np = v0 + edge0 * s + edge1 * t; + float dist = glm::distance(pos, np); + if(dist<minDist) { + nearestPnt = np; + minDist = dist; + } + } + + float val = minDist; + voxels[v] = std::max<float>(0.0f, val); + } + + ofstream outfile; + outfile.open(file, ios::out | ios::trunc); + outfile<<"PVM"<<endl; + //write dimensions + outfile<<to_string(m_surfDistDims.x)<<" " + <<to_string(m_surfDistDims.y)<<" " + <<to_string(m_surfDistDims.z)<<endl; + //format + outfile<<"8 1"<<endl; + //data + int c=0; + m_surfDistData.resize(m_surfDistDims.x*m_surfDistDims.y*m_surfDistDims.z); + for(int k = 0 ; k < m_surfDistDims.x; k++) { + for(int j = 0; j < m_surfDistDims.y; j++) { + for(int i = 0; i < m_surfDistDims.z; i++) { + float val = voxels[k*(m_surfDistDims.x*m_surfDistDims.y) + + j*(m_surfDistDims.x)+i]; + outfile<<(unsigned char)(max<float>(0.0,val)*float(UCHAR_MAX)); + m_surfDistData[c]=val; + c++; + } + } + } + outfile.close(); + map<int, bool>::iterator itUp = m_coordsUpMap.begin(); + for(; itUp!=m_coordsUpMap.end(); ++itUp) { + itUp->second=true; + } + + //set the chosen file as the texture layer + //setTextureLayersFolder(folder); + //m_attributesMap["texture_layers_folder"] + // ->initStrings(vector<string>(1, folder)); +} + +void RevealedModule::openSurfaceDistanceTexture(const string& file) { + parsePvm(file, m_surfDistDims, m_surfDistData); + + //ask for reinitializing texture uniform + map<int, bool>::iterator itUp = m_coordsUpMap.begin(); + for(; itUp!=m_coordsUpMap.end(); ++itUp) { + itUp->second=true; + } +} + +void RevealedModule::parsePvm(const std::string& file, + glm::ivec3& dimensions, + std::vector<float> &data) { + ifstream inpfile; + inpfile.open(file, ios::in); + cout<<"Loading pvm file "<<endl; + + //read comment line + string type; + getline(inpfile, type); + if(type.compare("PVM")==0) { + //read dimensions line + string dims; + getline(inpfile, dims); + istringstream dimsIss(dims); + string dim; + getline(dimsIss, dim, ' '); + dimensions.x = stoi(dim); + getline(dimsIss, dim, ' '); + dimensions.y = stoi(dim); + getline(dimsIss, dim, ' '); + dimensions.z = stoi(dim); + + //recreate data + data.resize(dimensions.x*dimensions.y*dimensions.z); + + //read data type line + string type; + getline(inpfile, type); + istringstream typeIss(type); + string typ; + getline(typeIss, typ, ' '); + + //read data depending on type + if(typ.compare("8")==0) { + for(int c=0; c<int(data.size()); ++c) { + unsigned char val = inpfile.get(); + data[c] = float(val)/float(UCHAR_MAX); + } + } + } + + cout<<"Done loading"<<endl; + inpfile.close(); + +} + +//Gradient +void RevealedModule::setGradientType(const std::string& type) { + int t=0; + vector<string>::iterator itType=m_gradientTypes.begin(); + for(; itType!=m_gradientTypes.end(); ++itType, ++t) { + if((*itType).compare(type)==0) { + m_gradientType = t; + } + } +} + +void RevealedModule::setGradientTexture(const std::string& f) { + Fl_Shared_Image* newImage = Fl_Shared_Image::get(f.c_str(), + m_texWidth, + m_texHeight); + if(newImage) { + m_gradientImage=newImage; + map<int, bool>::iterator itUp = m_gradientUpMap.begin(); + for(; itUp!=m_gradientUpMap.end(); ++itUp) { + itUp->second=true; + } + } +} + +//Density +void RevealedModule::setDensityType(const std::string& type) { + int t=0; + vector<string>::iterator itType=m_insideDensityTypes.begin(); + for(; itType!=m_insideDensityTypes.end(); ++itType, ++t) { + if((*itType).compare(type)==0) { + m_insideDensityType = t; + } + } +} + + +//Texture +void RevealedModule::setTexture(const std::string& f) { + Fl_Shared_Image* newImage = Fl_Shared_Image::get(f.c_str(), + m_texWidth, + m_texHeight); + if(newImage) { + m_insideImage=newImage; + //ask for reinitializing texture uniform + map<int, bool>::iterator itUp = m_insideUpMap.begin(); + for(; itUp!=m_insideUpMap.end(); ++itUp) { + itUp->second=true; + } + } +} + +void RevealedModule::setTextureOffset(const float& x, + const float& y, + const float& z) { + m_textureOffset[0]=x; + m_textureOffset[1]=y; + m_textureOffset[2]=z; +} + +void RevealedModule::setTextureScale(const float& x, + const float& y, + const float& z) { + m_textureScale[0]=(x!=0)?1.0/x:0; + m_textureScale[1]=(y!=0)?1.0/y:0; + m_textureScale[2]=(z!=0)?1.0/z:0; +} + +void RevealedModule::setTextureLayersFolder(const std::string& folder) { + dirent** filesList; + int nbFiles = fl_filename_list(folder.c_str(), &filesList, fl_alphasort); + m_layers.clear(); + for(int f=0; f<nbFiles; ++f) { + m_texWidth=640; + m_texHeight=480; + string fullName = folder+"/"+string(filesList[f]->d_name); + string extStr = string(fl_filename_ext(fullName.c_str())); + if(extStr.compare(".png")==0 || extStr.compare(".jpg")==0 + || extStr.compare(".pgm")==0 ) { + Fl_Shared_Image* newImage = Fl_Shared_Image::get(fullName.c_str(), + m_texWidth, + m_texHeight); + if(newImage) { + if(newImage->refcount()>0) { + newImage->reload(); + } + RevealedLayerImage* layIm = new RevealedLayerImage(); + layIm->m_image = newImage; + m_layers.push_back(layIm); + } + } + else if(extStr.compare(".ogg")==0 + || extStr.compare(".mp4")==0 + || extStr.compare(".mov")==0) { + cv::VideoCapture movie; + if(movie.open(fullName.c_str())) { + RevealedLayerVideo* layVi = new RevealedLayerVideo(m_texWidth, + m_texHeight); + layVi->setVideo(movie); + m_layers.push_back(layVi); + m_textureCanDelete=false; + } + } + else if(fl_filename_isdir(fullName.c_str()) && + string(filesList[f]->d_name)[0]!='.'){ //animation folder + dirent** anList; + int nbAn=fl_filename_list(fullName.c_str(), &anList, fl_alphasort); + vector<Fl_Shared_Image*> ans; + for(int f=0; f<nbAn; ++f) { + string anName = fullName+"/"+string(anList[f]->d_name); + string ext2Str = string(fl_filename_ext(anName.c_str())); + if(ext2Str.compare(".png")==0 || ext2Str.compare(".jpg")==0) { + Fl_Shared_Image* newAn=Fl_Shared_Image::get(anName.c_str(), + m_texWidth, + m_texHeight); + if(newAn) { + ans.push_back(newAn); + } + } + } + if(ans.size()>0) { + RevealedLayerAnim* layAn = new RevealedLayerAnim(); + layAn->m_images = ans; + m_layers.push_back(layAn); + m_textureCanDelete=false; + } + } + } + + if(m_layers.size()>0) { + //create data buffer of corresponding depth, width and height + if(m_layersData) { + delete [] m_layersData; + } + m_layersNb=m_layers.size(); + int nbBytes = m_texWidth*m_texHeight*m_layersNb*3; + m_layersData = new char[nbBytes]; + + //first texture update + int d=0; + vector<RevealedLayer*>::iterator itLa = m_layers.begin(); + for(; itLa!=m_layers.end(); ++itLa, ++d) { + (*itLa)->update(0, d, m_layersData, m_texWidth, m_texHeight); + if(m_textureCanDelete) { + (*itLa)->releaseData(); + } + } + + //ask for reinitializing texture uniform + map<int, bool>::iterator itUp = m_insideUpMap.begin(); + for(; itUp!=m_insideUpMap.end(); ++itUp) { + itUp->second=true; + } + } +} + +void RevealedModule::setAnimPos(const float& pos) { + vector<RevealedLayer*>::iterator itLa = m_layers.begin(); + for(; itLa!=m_layers.end(); ++itLa) { + (*itLa)->setAnimPos(pos/100.0); + } +} + +void RevealedModule::setAnimPlay(const bool& play) { + vector<RevealedLayer*>::iterator itLa = m_layers.begin(); + for(; itLa!=m_layers.end(); ++itLa) { + (*itLa)->setAnimPlay(play); + } + if(play) { + Reveal::getInstance()->addUpdateObserver(this); + } + else { + Reveal::getInstance()->removeUpdateObserver(this); + } +} + +void RevealedModule::setAnimSpeed(const float& speed) { + vector<RevealedLayer*>::iterator itLa = m_layers.begin(); + for(; itLa!=m_layers.end(); ++itLa) { + (*itLa)->setAnimSpeed(speed); + } +} + +//Surface +void RevealedModule::setSurface(const std::string& surface) { + int sur=0; + vector<string>::iterator itSur=m_surfaces.begin(); + for(; itSur!=m_surfaces.end(); ++itSur, ++sur) { + if((*itSur).compare(surface)==0) { + m_surface=sur; + } + } + map<int, bool>::iterator itUp = m_surfaceUpMap.begin(); + for(; itUp!=m_surfaceUpMap.end(); ++itUp) { + itUp->second=true; + } +} + +void RevealedModule::setSurfaceColor(const vector<float>& hsv) { + hsv2rgb(hsv, m_surfaceColor); +} + +void RevealedModule::setSurfaceTexture(const std::string& f) { + Fl_Shared_Image* newImage = Fl_Shared_Image::get(f.c_str(), + m_texWidth, + m_texHeight); + if(newImage) { + m_surfaceImage = newImage; + //ask for reinitializing texture uniform + map<int, bool>::iterator itUp = m_surfaceUpMap.begin(); + for(; itUp!=m_surfaceUpMap.end(); ++itUp) { + itUp->second=true; + } + } +} + +void RevealedModule::setSurfaceThickness(const float& surface) { + m_surfaceThickness=surface; +} + +void RevealedModule::gotAttributeListenersUpdate(Attribute* att) { + bool active=false; + vector<Attribute*>::iterator itAtt = m_revAttributes.begin(); + for(; itAtt!=m_revAttributes.end(); ++itAtt) { + if((*itAtt)->editListeners().size()>0) { + active=true; + } + } + if(active) { + Reveal::getInstance()->registerOutputRevealed(this); + } + else { + Reveal::getInstance()->unregisterOutputRevealed(this); + + //reset offsets + unsigned int off=0; + updateRevOffset(off); + m_revSize=0; + } +} + + +void RevealedModule::updateRevOffset(unsigned int& offset) { + //Test all reveal output attributes + m_revSize=1; + //inside is always active so that we can check for other attributes + m_revIns=0; + if(m_attributesMap["revealed_inside"]->editListeners().size()>0) { + m_revIns=m_revSize; + } + m_revSize+=1; + + m_revSurf=0; + if(m_attributesMap["revealed_surface"]->editListeners().size()>0) { + m_revSurf=m_revSize; + } + m_revSize+=1; + + m_revCent=0; + if(m_attributesMap["revealed_center"]->editListeners().size()>0 + || m_attributesMap["revealed_extent"]->editListeners().size()>0) { + m_revCent=m_revSize; + } + m_revSize+=6; + + m_revCol=0; + if(m_attributesMap["revealed_color"]->editListeners().size()>0) { + m_revCol=m_revSize; + } + m_revSize+=4; + + m_revHis=0; + if(m_attributesMap["revealed_histo"]->editListeners().size()>0) { + m_revHis=m_revSize; + } + m_revSize+=(m_outHistoSize+1); + + m_revVox=0; + if(m_attributesMap["revealed_voxels"]->editListeners().size()>0) { + m_revVox=m_revSize; + } + m_revSize+=(m_outVoxelSize*5); +} + +void RevealedModule::processReveal(const unsigned int& depthID, + const string& depthName, + const unsigned int& depthNb, + unsigned int* outputImg) { + + int offset = ((m_revID-1)*depthNb+(depthID-1))*m_revSize; + + //test if shape revealed + int revealed = outputImg[offset]; + bool send=false; + if(m_depthModsMap.find(depthID)==m_depthModsMap.end()) { + if(revealed) { + send=true; + m_depthModsMap[depthID]=true; + } + } + else { + send=true; + if(!revealed) { + m_depthModsMap.erase(depthID); + } + } + + if(send) { + vector<string> names(1, depthName); + m_attributesMap["revealed_name"]->setStringsIfChanged(names); + + if(m_revIns>0) { + vector<float> inside(1, outputImg[offset+m_revIns]); + m_attributesMap["revealed_inside"]->setFloatsIfChangedOrCount(inside); + } + + if(m_revSurf>0) { + vector<float> vals(1, outputImg[offset+m_revSurf]); + m_attributesMap["revealed_surface"]->setFloatsIfChangedOrCount(vals); + } + + if(m_revCent>0 && revealed&1) { + float fMinX = (1000.0-float(outputImg[offset+m_revCent]))/1000.0; + float fMaxX = float(outputImg[offset+m_revCent+1])/1000.0; + float fMinY = (1000.0-float(outputImg[offset+m_revCent+2]))/1000.0; + float fMaxY = float(outputImg[offset+m_revCent+3])/1000.0; + float fMinZ = (1000.0-float(outputImg[offset+m_revCent+4]))/1000.0; + float fMaxZ = float(outputImg[offset+m_revCent+5])/1000.0; + + vector<float> center = {(fMaxX+fMinX)/2.0f, + (fMaxY+fMinY)/2.0f, + (fMaxZ+fMinZ)/2.0f}; + m_attributesMap["revealed_center"]->setFloatsIfChanged(center); + vector<float> extent = {fabs(fMaxX-fMinX), + fabs(fMaxY-fMinY), + fabs(fMaxZ-fMinZ), + (fabs(fMaxX-fMinX) + + fabs(fMaxY-fMinY) + + fabs(fMaxZ-fMinZ))/3.0f}; + m_attributesMap["revealed_extent"]->setFloatsIfChanged(extent); + } + + if(m_revCol>0 && revealed&1) { + float nbPoints = float(outputImg[offset+m_revCol]); + if(nbPoints>0) { + vector<float> color = + {(float(outputImg[offset+m_revCol+1])/1000.0f)/float(nbPoints), + (float(outputImg[offset+m_revCol+2])/1000.0f)/float(nbPoints), + (float(outputImg[offset+m_revCol+3])/1000.0f)/float(nbPoints)}; + m_attributesMap["revealed_color"]->setFloatsIfChanged(color); + } + } + + if(m_revHis>0 && revealed&1) { + float nbPoints = float(outputImg[offset+m_revHis]); + if(nbPoints>0) { + vector<float> histo; + for(int i=1; i<m_outHistoSize+1; i++) { + histo.push_back(float(outputImg[offset+m_revHis+i])/nbPoints); + } + m_attributesMap["revealed_histo"]->setFloatsIfChanged(histo); + } + } + + if(m_revVox>0 && revealed&1) { + vector<float> voxels; + for(int i=0; i<m_outVoxelSize; i++) { + float nbPoints = float(outputImg[offset+m_revVox+i*5]); + if(nbPoints>0) { + //coords average + voxels.push_back((float(outputImg[offset+m_revVox+i*5+1])/1000.0) + / nbPoints); + voxels.push_back((float(outputImg[offset+m_revVox+i*5+2])/1000.0) + / nbPoints); + voxels.push_back((float(outputImg[offset+m_revVox+i*5+3])/1000.0) + / nbPoints); + //luminance average + voxels.push_back((float(outputImg[offset+m_revVox+i*5+4])/1000.0) + / nbPoints); + } + else { + voxels.push_back(0); + voxels.push_back(0); + voxels.push_back(0); + voxels.push_back(0); + } + } + m_attributesMap["revealed_voxels"]->setFloatsIfChanged(voxels); + } + } +} + +void RevealedModule::hsv2rgb(const vector<float>& hsv, + vector<float>& rgb) { + float hh, p, q, t, ff; + long i; + if(hsv[1] <= 0.0) { + rgb[0] = hsv[2]/100.0; + rgb[1] = hsv[2]/100.0; + rgb[2] = hsv[2]/100.0; + return; + } + hh = hsv[0]; + if(hh >= 360.0) { + hh = 0.0; + } + hh /= 60.0; + i = (long)hh; + ff = hh - i; + p = hsv[2]/100.0 * (1.0 - hsv[1]/100.0); + q = hsv[2]/100.0 * (1.0 - (hsv[1]/100.0 * ff)); + t = hsv[2]/100.0 * (1.0 - (hsv[1]/100.0 * (1.0 - ff))); + switch(i) { + case 0: + rgb[0] = hsv[2]/100.0; + rgb[1] = t; + rgb[2] = p; + break; + case 1: + rgb[0] = q; + rgb[1] = hsv[2]/100.0; + rgb[2] = p; + break; + case 2: + rgb[0] = p; + rgb[1] = hsv[2]/100.0; + rgb[2] = t; + break; + case 3: + rgb[0] = p; + rgb[1] = q; + rgb[2] = hsv[2]/100.0; + break; + case 4: + rgb[0] = t; + rgb[1] = p; + rgb[2] = hsv[2]/100.0; + break; + case 5: + default: + rgb[0] = hsv[2]/100.0; + rgb[1] = p; + rgb[2] = q; + break; + } +} + + +//----------------------Simulation-------------------------- +void* reactThreadFunction(void* pvParam) { + ((RevealedModule*)pvParam)->textureReact(); + return NULL; +} + +void RevealedModule::setTextureReact(const std::string& type) { + int t=0; + vector<string>::iterator itType=m_reactivityTypes.begin(); + for(; itType!=m_reactivityTypes.end(); ++itType, ++t) { + if((*itType).compare(type)==0) { + m_reactivityType = t; + } + } + //stop reactive thread + if(m_reactThread) { + m_reactActive=false; + m_reactThread->join(); + delete m_reactThread; + m_reactThread=NULL; + } + + //start it again if reactive + if(m_reactivityType>0) { + m_reactActive=true; + m_reactThread = new std::thread(reactThreadFunction, this); + } +} + +void RevealedModule::textureReact() { + while(m_reactActive) { + //get voxel output from attribute + m_reactLock.lock(); + vector<float> voxels(m_attributesMap["revealed_voxels"]->getFloats()); + int inside = m_attributesMap["revealed_inside"]->getFloats()[0]; + m_reactLock.unlock(); + + //reset input texture + for(int v=0; v<m_voxSize; ++v) { + m_reactTexInput[v]=0; + } + + //store revealed in input texture + if(inside>0) { + for(int v=0; v<m_outVoxelSize; ++v) { + if(voxels[v*4]>0) { //if coord active + int coord = int((voxels[v*4])*float(m_voxDim)) //x + + int((voxels[v*4+1])*float(m_voxDim))*m_voxDim //y + + int((voxels[v*4+2])*float(m_voxDim))*m_voxDim*m_voxDim; + m_reactTexInput[coord] = 1.0; + } + } + } + + //update voxels + float step=1; + for(int v=0; v<m_voxSize; ++v) { + if(m_reactTexInput[v]>0) { + m_reactTexInternal[v]=min<float>(m_reactTexInternal[v]+step, + 250.0); + } + else { + m_reactTexInternal[v]=max<float>(m_reactTexInternal[v]-step, + 0.0); + } + } + + //update react texture and update map + m_reactLock.lock(); + for(int v=0; v<m_voxSize; ++v) { + m_reactTexOutput[v*3]=char(10*sqrt(m_reactTexInternal[v])); + m_reactTexOutput[v*3+1]=char(10*sqrt(m_reactTexInternal[v])); + m_reactTexOutput[v*3+2]=char(10*sqrt(m_reactTexInternal[v])); + } + for(auto& m : m_reactUpMap) { + m.second=true; + } + m_reactLock.unlock(); + usleep(10000); + } +} + + +//-----------------------------Layers------------------------------------- + +RevealedLayer::RevealedLayer(): m_playing(false), m_speed(1), + m_update(true), m_accumTimeDiff(0){} + +bool RevealedLayerImage::update(const int& timeDiffMs, const int& depth, + char* data, + const int& width, const int& height) { + if(m_update) { + for(int i=0; i<width; ++i) { + for(int j=0; j<height; ++j) { + if(m_image->d()==4) { + data[(depth*width*height+j*width+i)*3] + =m_image->data()[0][(j*m_image->w()+i)*m_image->d()] + *((m_image->data()[0][(j*m_image->w()+i)*m_image->d()+3] + ==0)?0:1); + data[(depth*width*height+j*width+i)*3+1] + =m_image->data()[0][(j*m_image->w()+i)*m_image->d()+1] + *((m_image->data()[0][(j*m_image->w()+i)*m_image->d()+3] + ==0)?0:1); + data[(depth*width*height+j*width+i)*3+2] + =m_image->data()[0][(j*m_image->w()+i)*m_image->d()+2] + *((m_image->data()[0][(j*m_image->w()+i)*m_image->d()+3] + ==0)?0:1); + } + else { + data[(depth*width*height+j*width+i)*3] + = m_image->data()[0][(j*m_image->w()+i)*m_image->d()]; + data[(depth*width*height+j*width+i)*3+1] + = m_image->data()[0][(j*m_image->w()+i)*m_image->d()+1]; + data[(depth*width*height+j*width+i)*3+2] + = m_image->data()[0][(j*m_image->w()+i)*m_image->d()+2]; + } + } + } + m_update=false; + } + return false; +} + +bool RevealedLayerVideo::update(const int& timeDiffMs, const int& depth, + char* data, + const int& width, const int& height) { + bool res=false; + //try lock + if(m_gotFrame) { + if(m_lock.try_lock()) { + //copy frame to data + memcpy(&data[depth*width*height*3], &m_data[0], width*height*3); + res=true; + m_gotFrame=false; + m_lock.unlock(); + } + } + + return res; +} + + +void RevealedLayerVideo::read() { + m_video.set(cv::CAP_PROP_POS_FRAMES, 0); + while(m_playing) { + + int nbFrames=0; + bool gotFrame=false; + if(m_playing) { + + timeval curTime, timeDiff; + gettimeofday(&curTime,NULL); + timersub(&curTime, &m_prevTime, &timeDiff); + int timeDiffMs = timeDiff.tv_sec*1000.0+timeDiff.tv_usec/1000.0; + m_accumTimeDiff=float(timeDiffMs)*m_speed; + int supFrame = m_accumTimeDiff + /(1000.0/m_vidFps); + if(supFrame>m_curFrame) { + m_update=true; + nbFrames=supFrame-m_curFrame; + } + } + + for(; nbFrames>0; nbFrames--) { + try { + //if(!m_video.read(m_frame)) { + if(!m_video.grab()) { + /* + m_video.set(cv::CAP_PROP_POS_FRAMES, 0); + gettimeofday(&m_prevTime,NULL); + m_curFrame=0; + */ + m_playing=false; + } + else { + gotFrame=true; + m_curFrame++; + } + }catch(const std::exception& e) { + + } + } + if(m_update) { + if(gotFrame) { + cv::Mat frame; + m_video.retrieve(frame); + m_lock.lock(); + float scaX = float(m_vidWidth)/float(m_texWidth); + float scaY = float(m_vidHeight)/float(m_texHeight); + for(float i=0; i<m_texWidth; ++i) { + for(float j=0; j<m_texHeight; ++j) { + m_data[int(j*m_texWidth+i)*3] + = frame.data[(int(j*scaY)*m_vidWidth+int(i*scaX))*3+2]; + m_data[int(j*m_texWidth+i)*3+1] + = frame.data[(int(j*scaY)*m_vidWidth+int(i*scaX))*3+1]; + m_data[int(j*m_texWidth+i)*3+2] + = frame.data[(int(j*scaY)*m_vidWidth+int(i*scaX))*3]; + } + } + m_gotFrame=true; + m_lock.unlock(); + } + m_update=false; + } + + + /* + if(m_playing) { + timeval curTime, timeDiff; + gettimeofday(&curTime,NULL); + timersub(&curTime, &m_prevTime, &timeDiff); + int timeDiffMs = timeDiff.tv_sec*1000.0+timeDiff.tv_usec/1000.0; + m_accumTimeDiff=float(timeDiffMs)*m_speed; + int nextFrame = m_accumTimeDiff + /(1000.0/m_vidFps); + if(nextFrame!=m_curFrame) { + if(nextFrame>=m_vidFrames) { + m_curFrame = nextFrame-m_vidFrames;; + } + else { + m_curFrame=nextFrame; + } + m_update=true; + } + } + + cout<<"blup?"<<endl; + if(m_update) { + cout<<"blip?"<<endl; + m_video.set(cv::CAP_PROP_POS_FRAMES, m_curFrame); + if(m_video.read(m_frame)) { + m_lock.lock(); + float scaX = m_vidWidth/m_texWidth; + float scaY = m_vidHeight/m_texHeight; + for(int i=0; i<m_texWidth; ++i) { + for(int j=0; j<m_texHeight; ++j) { + m_data[(j*m_texWidth+i)*3] + = m_frame.data[int(j*scaY*m_vidWidth+i*scaX)*3+2]; + m_data[(j*m_texWidth+i)*3+1] + = m_frame.data[int(j*scaY*m_vidWidth+i*scaX)*3+1]; + m_data[(j*m_texWidth+i)*3+2] + = m_frame.data[int(j*scaY*m_vidWidth+i*scaX)*3]; + } + } + m_gotFrame=true; + m_lock.unlock(); + m_update=false; + } + } + */ + + /* + //img test + if(m_playing) { + + timeval curTime, timeDiff; + gettimeofday(&curTime,NULL); + timersub(&curTime, &m_prevTime, &timeDiff); + int timeDiffMs = timeDiff.tv_sec*1000.0+timeDiff.tv_usec/1000.0; + m_accumTimeDiff=float(timeDiffMs)*m_speed; + int nextFrame = m_accumTimeDiff + /(1000.0/m_vidFps); + if(nextFrame!=m_curFrame) { + if(nextFrame>=m_vidFrames) { + m_curFrame = nextFrame-m_vidFrames;; + } + else { + m_curFrame=nextFrame; + } + m_update=true; + } + } + + if(m_update) { + m_lock.lock(); + memcpy(&m_data[0], + &m_vidData[m_curFrame*m_texWidth*m_texHeight*3], + m_texWidth*m_texHeight*3); + m_gotFrame=true; + m_lock.unlock(); + } + */ + + + + usleep(5000); + } +} + +void RevealedLayerVideo::setVideo(cv::VideoCapture vid) { + m_video=vid; + m_vidWidth = m_video.get(cv::CAP_PROP_FRAME_WIDTH); + m_vidHeight = m_video.get(cv::CAP_PROP_FRAME_HEIGHT); + m_vidFps = vid.get(cv::CAP_PROP_FPS); + m_vidFrames = vid.get(cv::CAP_PROP_FRAME_COUNT); + + /* + //test with images + m_video=vid; + m_vidWidth = vid.get(cv::CAP_PROP_FRAME_WIDTH); + m_vidHeight = vid.get(cv::CAP_PROP_FRAME_HEIGHT); + + if(m_vidData!=NULL) { + delete [] m_vidData; + } + + m_vidData = new char[m_vidFrames*m_texWidth*m_texHeight*3]; + float scaX = m_vidWidth/m_texWidth; + float scaY = m_vidHeight/m_texHeight; + + for(int f=0; f<m_vidFrames; ) { + if(vid.read(m_frame)) { + for(int i=0; i<m_texWidth; ++i) { + for(int j=0; j<m_texHeight; ++j) { + m_vidData[(f*m_texWidth*m_texHeight+j*m_texWidth+i)*3] + = m_frame.data[int(j*scaY*m_vidWidth+i*scaX)*3+2]; + m_vidData[(f*m_texWidth*m_texHeight+j*m_texWidth+i)*3+1] + = m_frame.data[int(j*scaY*m_vidWidth+i*scaX)*3+1]; + m_vidData[(f*m_texWidth*m_texHeight+j*m_texWidth+i)*3+2] + = m_frame.data[int(j*scaY*m_vidWidth+i*scaX)*3]; + } + } + f++; + } + usleep(1000); + } + + vid.release(); + */ +} + +void RevealedLayerVideo::setAnimPos(const float& pos) { + m_video.set(cv::CAP_PROP_POS_FRAMES, + float(m_video.get(cv::CAP_PROP_FRAME_COUNT))*pos); + m_update=true; +} + +RevealedLayerAnim::RevealedLayerAnim():RevealedLayer() { + m_current=0; +} + +bool RevealedLayerAnim::update(const int& timeDiffMs, const int& depth, + char* data, + const int& width, const int& height) { + bool res=false; + if(m_playing) { + m_accumTimeDiff+=float(timeDiffMs)*m_speed; + if(m_accumTimeDiff>200.0) { + m_current++; + if(m_current>=int(m_images.size())) { + m_current=0; + } + m_accumTimeDiff=0; + m_update=true; + } + } + if(m_update) { + Fl_Shared_Image* im = m_images[m_current]; + for(int i=0; i<width; ++i) { + for(int j=0; j<height; ++j) { + data[(depth*width*height+j*width+i)*3] + =im->data()[0][(j*im->w()+i)*im->d()]; + data[(depth*width*height+j*width+i)*3+1] + =im->data()[0][(j*im->w()+i)*im->d()+1]; + data[(depth*width*height+j*width+i)*3+2] + =im->data()[0][(j*im->w()+i)*im->d()+2]; + } + } + res=true; + m_update=false; + } + return res; +} + +void RevealedLayerAnim::setAnimPos(const float& pos) { + m_current = float(m_images.size()-1)*pos; + m_update=true; +} + +/* + GLenum err; + while ((err = glGetError()) != GL_NO_ERROR) { + } + while ((err = glGetError()) != GL_NO_ERROR) { + string error; + switch(err) { + case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break; + case GL_INVALID_ENUM: error="INVALID_ENUM"; break; + case GL_INVALID_VALUE: error="INVALID_VALUE"; break; + case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break; + case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break; + } + cout << "OpenGL error before draw: " << error << endl; + } +*/ + diff --git a/src/modules/RevealedModule.hpp b/src/modules/RevealedModule.hpp new file mode 100644 index 0000000..72b4ff4 --- /dev/null +++ b/src/modules/RevealedModule.hpp @@ -0,0 +1,469 @@ +/*************************************************************************** + * RevealedModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef RevealedModule_h +#define RevealedModule_h + +#include "GeomModule.hpp" +#include "opencv2/opencv.hpp" +#include <FL/Fl_Shared_Image.H> +#include <sys/time.h> +#include <thread> +#include <mutex> + +struct RevealedLayer; + +class RevealedModule : public virtual GeomModule { + public: + RevealedModule(); + virtual ~RevealedModule(); + void deleteModule(); + + void draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + std::map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& comp=0); + + static void colorCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setColor(vals); + } + virtual void setColor(const std::vector<float>&); + + static void insideVisibleCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<RevealedModule*>(mod)->setInsideVisible(vals[0]); + } + virtual void setInsideVisible(bool v){m_insideVisible=v;} + + static void insideAxesCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedModule*>(mod)->setInsideAxes(vals[0]); + } + virtual void setInsideAxes(const std::string&); + + static void insideStructureCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedModule*>(mod)->setInsideStructure(vals[0]); + } + virtual void setInsideStructure(const std::string&); + + virtual void generateSurfaceDistanceTexture(const std::string& f); + virtual void openSurfaceDistanceTexture(const std::string& f); + + static void structureRatioCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setStructureRatio(vals[0]); + } + virtual void setStructureRatio(const float& r){m_structureRatio=r;} + + //Gradient + static void gradientAlphaCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setGradientAlpha(vals[0]); + } + virtual void setGradientAlpha(const float& a){m_insideGradientAlpha=a;} + + static void gradientTypeCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedModule*>(mod)->setGradientType(vals[0]); + } + virtual void setGradientType(const std::string&); + + static void gradientStepsCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<RevealedModule*>(mod)->setGradientSteps(vals[0]); + } + virtual void setGradientSteps(const int& s){m_insideGradientSteps=s;} + + static void gradientCurveRatioCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setGradientCurveRatio(vals[0]); + } + virtual void setGradientCurveRatio(const float& r){ + m_insideGradientCurveRatio=r; + } + + static void gradientTextureCallback(Module* mod, + const std::string& val) { + dynamic_cast<RevealedModule*>(mod)->setGradientTexture(val); + } + virtual void setGradientTexture(const std::string&); + + + //Texture + static void textureAlphaCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setTextureAlpha(vals[0]); + } + virtual void setTextureAlpha(const float& a){m_insideTextureAlpha=a;} + + static void textureBlendCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<RevealedModule*>(mod)->setTextureBlend(vals[0]); + } + virtual void setTextureBlend(bool b); + + static void textureGrayscaleCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<RevealedModule*>(mod)->setTextureGrayscale(vals[0]); + } + virtual void setTextureGrayscale(bool b){m_textureGrayscale=b;} + + + static void textureCallback(Module* mod, const std::string& f) { + dynamic_cast<RevealedModule*>(mod)->setTexture(f); + } + virtual void setTexture(const std::string& f); + + static void textureLayersFolderCallback(Module* mod, + const std::string& f) { + dynamic_cast<RevealedModule*>(mod)->setTextureLayersFolder(f); + } + virtual void setTextureLayersFolder(const std::string& f); + + + static void textureOffsetCallback(Module* mod, + const std::vector<float>& f) { + dynamic_cast<RevealedModule*>(mod) + ->setTextureOffset(f[0],f[1],f[2]); + } + virtual void setTextureOffset(const float& x, + const float& y, + const float& z); + static void textureScaleCallback(Module* mod, + const std::vector<float>& f) { + dynamic_cast<RevealedModule*>(mod) + ->setTextureScale(f[0],f[1],f[2]); + } + virtual void setTextureScale(const float& x, + const float& y, + const float& z); + + static void textureReactCallback(Module* mod, + const std::vector<std::string>& s) { + dynamic_cast<RevealedModule*>(mod)->setTextureReact(s[0]); + } + virtual void setTextureReact(const std::string& s); + + static void animPosCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setAnimPos(vals[0]); + } + virtual void setAnimPos(const float&); + static void animPlayCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<RevealedModule*>(mod)->setAnimPlay(vals[0]); + } + virtual void setAnimPlay(const bool&); + static void animSpeedCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setAnimSpeed(vals[0]); + } + virtual void setAnimSpeed(const float&); + + //Density + static void densityAlphaCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setDensityAlpha(vals[0]); + } + virtual void setDensityAlpha(const float& a){m_insideDensityAlpha=a;} + + static void densityTypeCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedModule*>(mod)->setDensityType(vals[0]); + } + virtual void setDensityType(const std::string& t); + + static void densityRatioCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setDensityRatio(vals[0]); + } + virtual void setDensityRatio(const float& r){m_insideDensityRatio=r;} + + static void densitySizeCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setDensitySize(vals[0]); + } + virtual void setDensitySize(const float& s){m_insideDensitySize=s;} + + static void densityCurveRatioCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setDensityCurveRatio(vals[0]); + } + virtual void setDensityCurveRatio(const float& r) { + m_insideDensityCurveRatio=r; + } + + //Surface + static void surfaceCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedModule*>(mod)->setSurface(vals[0]); + } + virtual void setSurface(const std::string&); + + static void surfaceColorCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setSurfaceColor(vals); + } + virtual void setSurfaceColor(const std::vector<float>&); + + static void surfaceThicknessCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedModule*>(mod)->setSurfaceThickness(vals[0]); + } + virtual void setSurfaceThickness(const float&); + + static void surfaceTextureCallback(Module* mod, const std::string& f) { + dynamic_cast<RevealedModule*>(mod)->setSurfaceTexture(f); + } + virtual void setSurfaceTexture(const std::string& f); + + //Revealed + static void revnamCallback(Module* mod, + const std::vector<std::string>& vals){} + static void revsurCallback(Module* mod,const std::vector<float>& vals){} + static void revinsCallback(Module* mod,const std::vector<float>& vals){} + static void revcentCallback(Module* mod,const std::vector<float>&vals){} + static void revextCallback(Module* mod,const std::vector<float>&vals){} + static void revcolCallback(Module* mod,const std::vector<float>& vals){} + static void revhistoCallback(Module* mod,const std::vector<float>&vals){} + static void revvoxelCallback(Module* mod,const std::vector<float>&vals){} + + + inline bool isOutputActive(){return m_outputActive;} + + inline void setRevID(const unsigned int& id) { + m_revID = id; + m_revIDBit = double(1<<(int(id)%15)); + } + inline const unsigned int& getRevID(){return m_revID;} + inline const float& getRevIDBit(){return m_revIDBit;} + void updateRevOffset(unsigned int& offset); + + void gotAttributeListenersUpdate(Attribute*); + + + //Updating + virtual void update(const int& timeDiffMs); + + virtual void processReveal(const unsigned int& depthId, + const std::string& depthName, + const unsigned int& depthNb, + unsigned int* outputImg); + void textureReact(); + + + //utilities + void hsv2rgb(const std::vector<float>& hsv, + std::vector<float>& rgb); + + void addRevealedAttributes(); + void addRevealedInsideAttributes(); + void addRevealedInsideStructureAttributes(); + void addRevealedInsideGradientAttributes(); + void addRevealedInsideDensityAttributes(); + void addRevealedInsideTextureAttributes(); + void addRevealedOutputAttributes(); + + void parsePvm(const std::string& file, + glm::ivec3& dimensions, + std::vector<float>& data); + + protected: + unsigned int m_revID; + float m_revIDBit; + std::vector<float> m_color; + std::vector<float> m_surfaceColor; + int m_shapeGeom; + int m_surface; + std::vector<std::string> m_surfaces; + float m_surfaceThickness; + + int m_inside; + bool m_insideVisible; + + std::vector<std::string> m_insideAxes; + int m_insideStructure; + std::vector<std::string> m_insideStructures; + float m_structureRatio; + + float m_insideGradientAlpha; + int m_gradientType; + std::vector<std::string> m_gradientTypes; + int m_insideGradientSteps; //0-10 + float m_insideGradientCurveRatio; //sign/linearity (-y -> -pow(x,y)) + std::map<int, bool> m_gradientUpMap; + std::map<int, GLuint> m_gradientIDMap; + Fl_Shared_Image* m_gradientImage; + + float m_insideDensityAlpha; + int m_insideDensityType; + std::vector<std::string> m_insideDensityTypes; + float m_insideDensityRatio; + float m_insideDensitySize; + float m_insideDensityCurveRatio; + + float m_insideTextureAlpha; + bool m_insideTextureBlend; + float m_textureOffset[3]; + float m_textureScale[3]; + std::vector<std::string> m_reactivityTypes; + int m_reactivityType; + bool m_textureGrayscale; + bool m_textureCanDelete; + + std::map<int, bool> m_surfaceUpMap; + std::map<int, GLuint> m_surfaceIDMap; + Fl_Shared_Image* m_surfaceImage; + char* m_layersData; + std::map<int, bool> m_insideUpMap; + std::map<int, GLuint> m_insideIDMap; + int m_layersNb; + std::vector<Fl_Shared_Image*> m_layersImages; + Fl_Shared_Image* m_insideImage; + std::vector<RevealedLayer*> m_layers; + std::map<int, GLuint> m_coordsIDMap; + std::map<int, bool> m_coordsUpMap; + std::map<unsigned int, bool> m_depthModsMap; + int m_volumeTextureWidth; + int m_volumeTextureHeight; + + //std::vector<std::string> m_texMirrors; + + bool m_outputActive; + std::vector<Attribute*> m_revAttributes; + int m_revOffset, m_revSize; + int m_revSurf, m_revIns, m_revCent, m_revCol, m_revHis, m_revVox; + int m_outShapeSize; + int m_outVoxelSize; + int m_outHistoSize; + int m_outDepthSize; + int m_outNbDepth; + + std::thread* m_reactThread; + std::mutex m_reactLock; + bool m_reactActive; + int m_voxDim; + int m_voxSize; + float *m_reactTexInput, *m_reactTexInternal; + char *m_reactTexOutput; + std::map<int, bool> m_reactUpMap; + std::map<int, GLuint> m_reactIDMap; + + glm::ivec3 m_surfDistDims; + std::vector<float> m_surfDistData; + + int m_timeDiffMs; +}; + +class RevealedLayer { + public: + RevealedLayer(); + virtual ~RevealedLayer(){} + virtual bool update(const int& timeDiffMs, const int& depth, + char* data, const int& width, const int& height)=0; + virtual void setAnimPos(const float& pos){} + virtual void setAnimPlay(const bool& play){m_playing=play;} + virtual void setAnimSpeed(const float& speed){m_speed=speed;} + virtual void releaseData(){} + protected: + bool m_playing; + float m_speed; + bool m_update; + int m_accumTimeDiff; +}; + +class RevealedLayerVideo: public RevealedLayer { + public: + RevealedLayerVideo(const int& w, const int& h):RevealedLayer(){ + m_texWidth=w; + m_texHeight=h; + m_thread=NULL; + m_data = new char[w*h*3]; + m_gotFrame=false; + m_vidData = NULL; + } + virtual bool update(const int& timeDiffMs, const int& depth, + char* data, const int& width, const int& height); + virtual void setAnimPos(const float& pos); + virtual void setVideo(cv::VideoCapture vid); + static void* videoReadThreadFunction(void* pvParam) { + RevealedLayerVideo *pThis=(RevealedLayerVideo*)pvParam; + pThis->read(); + return NULL; + } + + virtual void setAnimPlay(const bool& play) { + if(play && !m_playing) { + m_playing=play; + gettimeofday(&m_prevTime,NULL); + m_curFrame=0; + m_thread = new std::thread(videoReadThreadFunction, this); + } + else if(!play && m_playing) { + if(m_thread) { + m_playing=play; + m_thread->join(); + delete m_thread; + m_thread=NULL; + } + } + } + void read(); + + cv::VideoCapture m_video; + cv::Mat m_frame; + int m_texWidth, m_texHeight; + int m_vidWidth, m_vidHeight; + int m_vidFrames, m_vidFps; + char* m_vidData; + std::thread* m_thread; + std::mutex m_lock; + bool m_gotFrame; + char* m_data; + timeval m_prevTime; + int m_curFrame; +}; + +class RevealedLayerImage : public RevealedLayer { + public: + RevealedLayerImage():RevealedLayer(){} + virtual bool update(const int& timeDiffMs, const int& depth, + char* data, const int& width, const int& height); + virtual void releaseData(){m_image->release();} + Fl_Shared_Image* m_image; +}; + +class RevealedLayerAnim : public RevealedLayer { + public: + RevealedLayerAnim(); + virtual bool update(const int& timeDiffMs, const int& depth, + char* data, const int& width, const int& height); + virtual void setAnimPos(const float& pos); + std::vector<Fl_Shared_Image*> m_images; + int m_current; +}; + +#endif + diff --git a/src/modules/RevealedPathModule.cpp b/src/modules/RevealedPathModule.cpp new file mode 100644 index 0000000..b78eed0 --- /dev/null +++ b/src/modules/RevealedPathModule.cpp @@ -0,0 +1,446 @@ +/*************************************************************************** + * RevealedPathModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "RevealedPathModule.hpp" + +#include <iostream> +#include <glm/gtx/quaternion.hpp> + +#include "../Reveal.hpp" + +#include "../geoms/Geometry.hpp" + +using namespace std; +using namespace glm; + +RevealedPathModule::RevealedPathModule(): RevealedModule() { + m_type="Path"; + m_name="path"; + + m_pathGeom = new Geometry(); + Reveal::getInstance()->registerGeom(m_pathGeom); + m_pathGeom->registerModule(this); + + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + addVisibleFromAttribute(); + addRevealedByAttribute(); + addAttribute(new Attribute("add_point", + Attribute::ACTION_FLOAT_ATTRIBUTE, + addPointCallback, this, 3)); + addAttribute(new Attribute("add_module_point", + Attribute::ACTION_STRING_ATTRIBUTE, + addModulePointCallback, this, 1)); + addAttribute(new Attribute("remove_last_point", + Attribute::ACTION_ATTRIBUTE, + removePointCallback, this)); + addAttribute(new Attribute("clear_points", + Attribute::ACTION_ATTRIBUTE, + clearPointsCallback, this)); + addAttribute(new Attribute("thickness", + Attribute::FLOAT_ATTRIBUTE, + thicknessCallback, this, 1)); + addAttribute(new Attribute("edges", + Attribute::INT_ATTRIBUTE, + edgesCallback, this, 1)); + //addTransformationAttributes(); + addRevealedAttributes(); + addRevealedInsideAttributes(); + addRevealedOutputAttributes(); + + m_attributesMap["inside_structure"]->setStrings(vector<string>(1,"along_z")); + m_attributesMap["surface_thickness"]->setFloats(vector<float>(1,0.05)); + + m_attributesMap["thickness"]->setFloats(vector<float>(1,100)); + m_attributesMap["edges"]->setInts(vector<int>(1,8)); + m_attributesMap["gradient_type"]->setStrings(vector<string>(1, "along_z")); + vector<string> mods(1, "select_module"); + m_attributesMap["add_module_point"]->editStringValuesChoices() + .assign(1,mods); + Reveal::getInstance()->addModuleListObserver(this); + + m_shapeGeom=Reveal::GEOM_PATH; + m_pathInitialised=2; +} + +RevealedPathModule::~RevealedPathModule() { + Reveal::getInstance()->unregisterGeom(m_pathGeom); +} + +void RevealedPathModule::load(xmlNodePtr node) { + Module::load(node); + xmlNodePtr pntsNode; + for(pntsNode=node->children; pntsNode; pntsNode=pntsNode->next){ + if(pntsNode->type == XML_ELEMENT_NODE && + !xmlStrcmp(pntsNode->name, (const xmlChar *) "Points")) { + xmlNodePtr pntNode; + for(pntNode=pntsNode->children; pntNode; pntNode=pntNode->next){ + if(pntNode->type == XML_ELEMENT_NODE) { + if(!xmlStrcmp(pntNode->name, (const xmlChar *) "Point")) { + m_points.push_back(new PathPoint(glm::vec4(0,0,0,1))); + m_points.back()->loadPnt(pntNode); + } + else if(!xmlStrcmp(pntNode->name, + (const xmlChar *) "PointModule")) { + m_points.push_back(new PathPointModule(this)); + m_points.back()->loadPnt(pntNode); + } + } + } + } + } + refreshGeometry(); +} + +xmlNodePtr RevealedPathModule::save(xmlNodePtr parentNode) { + xmlNodePtr newNode = Module::save(parentNode); + xmlNodePtr pntsNode = xmlNewChild(newNode, NULL, BAD_CAST"Points", NULL); + vector<PathPoint*>::iterator itPnt = m_points.begin(); + for(; itPnt!=m_points.end(); ++itPnt) { + (*itPnt)->savePnt(pntsNode); + } + return newNode; +} + +void RevealedPathModule::addPoint(const float& x, + const float& y, + const float& z) { + m_points.push_back(new PathPoint(glm::vec4(x, y, z, 1))); + refreshGeometry(); +} + +void RevealedPathModule::updateModulesList(const map<string, Module*>& mods) { + + vector<vector<string> >& moduleNames = m_attributesMap["add_module_point"] + ->editStringValuesChoices(); + moduleNames.clear(); + moduleNames.push_back(vector<string>()); + map<string, Module*>::const_iterator itMod = mods.begin(); + for(; itMod!=mods.end(); ++itMod) { //select names from scene modules + if(itMod->first.find("/revil/scene/")==0) { + moduleNames[0].push_back(itMod->first); + } + } +} + +void RevealedPathModule::addModulePoint(const std::string& moduleStr) { + Module* mod = NULL; + mod = Reveal::getInstance()->findModule(moduleStr); + if(mod) { + m_points.push_back(new PathPointModule(this, mod)); + refreshGeometry(); + } +} + +void RevealedPathModule::removePoint() { + if(m_points.size()>0) { + PathPoint* pnt = m_points.back(); + delete pnt; + m_points.pop_back(); + refreshGeometry(); + } +} + +void RevealedPathModule::clearPoints() { + for(unsigned int p=0; p<m_points.size(); ++p) { + PathPoint* pnt = m_points[p]; + delete pnt; + } + m_points.clear(); + refreshGeometry(); +} + +void RevealedPathModule::refreshGeometry() { + //refresh local position of all points + for(unsigned int p=0; p<m_points.size(); ++p) { + m_points[p]->refreshPos(); + } + + vector<GLfloat>& vertices = m_pathGeom->editVertexBufferData(); + vector<GLuint>& indices = m_pathGeom->editIndexBufferData(); + vector<int>& sizes = m_pathGeom->editCompoSizes(); + + vertices.clear(); + indices.clear(); + sizes.clear(); + m_compoLocalSizes.clear(); + m_compoVertices.clear(); + m_compoRots.clear(); + + m_subShapeInvMats.clear(); + + if(m_points.size()>0) { + //create all vertices + glm::vec3 dirZ(0, 0, 1); + unsigned int preC=0; + unsigned int nexC=0; + for(unsigned int p=0; p<m_points.size(); ++p) { + glm::mat4 rot=glm::mat4(1.0); + + //find the corresponding component + if(m_points.size()<3) { + preC=0; + nexC=0; + } + else { + preC=(p<=0)?0:int(p)-1; + nexC=(p>=(m_points.size()-1))?p-1:p; + } + + glm::vec3 dir(0.0); + if(p>0) { + dir = glm::vec3(m_points[p]->editPos() + - m_points[int(p)-1]->editPos()); + glm::vec3 dirN = normalize(dir); + //rot = toMat4(rotation(dirZ, dirN)); + glm::vec3 markR(1.0,0.0,0.0); + glm::vec3 markUp = + glm::normalize(glm::cross(markR, dirN)); + rot = glm::mat4x4( //r,up,n + markR[0], markR[1], markR[2], 0.0, + markUp[0], markUp[1], markUp[2],0.0, + dirN[0], dirN[1], dirN[2], 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + m_compoLocalSizes[preC] = + glm::vec4(m_thickness, m_thickness, length(dir), 1.0); + + //build and store sub inverse matrix + mat4 subMat = scale(vec3(m_thickness, + m_thickness, + length(dir))); + subMat = rot * subMat; + subMat = translate(vec3(m_points[int(p)-1]->editPos() + + vec4(dir.x/2.0,dir.y/2.0,dir.z/2.0,1.0))) + * subMat; + m_subShapeInvMats.push_back(inverse(subMat)); + } + else if(m_points.size()>1) { + dir = glm::vec3(m_points[p+1]->editPos() + - m_points[p]->editPos()); + glm::vec3 dirN = normalize(dir); + rot = toMat4(rotation(dirZ, dirN)); + m_compoLocalSizes[preC] = + glm::vec4(m_thickness,m_thickness, length(dir), 1.0); + } + + //add the vertices + float angle=0; + float angleStep=M_PI*2.0/float(m_nbEdges); + for(int v=0; v<m_nbEdges; ++v, angle+=angleStep) { + glm::vec4 pnt = m_points[p]->editPos() + +rot*glm::vec4(cos(angle)*m_thickness, + sin(angle)*m_thickness, + 0, 1); + vertices.push_back(pnt[0]); + vertices.push_back(pnt[1]); + vertices.push_back(pnt[2]); + vertices.push_back(0); + vertices.push_back(0); + + m_compoVertices[nexC].push_back(pnt); + m_compoVertices[preC].push_back(pnt); + } + + //save rotations/dirs + m_compoRots[nexC]=rot; + m_compoRots[preC]=rot; + } + + //indices + if(m_points.size()>1) { + //create segments and backs + for(int s=0; s<int(m_points.size())-1; ++s) { + for(int v=0; v<m_nbEdges-2; ++v) { + indices.push_back(s*m_nbEdges+v); + indices.push_back(s*m_nbEdges+m_nbEdges-1); + indices.push_back(s*m_nbEdges+v+1); + } + for(int v=0; v<m_nbEdges; ++v) { + indices.push_back((s*m_nbEdges)+v); + indices.push_back((s*m_nbEdges)+(v+1)%m_nbEdges); + indices.push_back(((s+1)*m_nbEdges)+v); + + indices.push_back(((s+1)*m_nbEdges)+v); + indices.push_back((s*m_nbEdges)+(v+1)%m_nbEdges); + indices.push_back(((s+1)*m_nbEdges)+(v+1)%m_nbEdges); + } + for(int v=0; v<m_nbEdges-2; ++v) { + indices.push_back((s+1)*m_nbEdges+v); + indices.push_back((s+1)*m_nbEdges+v+1); + indices.push_back((s+1)*m_nbEdges+m_nbEdges-1); + } + sizes.push_back(m_nbEdges*6+2*(m_nbEdges-2)*3); + } + } + } + m_pathGeom->refresh(); +} + +void RevealedPathModule::setThickness(const float& t) { + if(t>0) { + m_thickness=t; + } + refreshGeometry(); +} + +void RevealedPathModule::setEdges(const int& e) { + if(e>=3) { + m_nbEdges=e; + } + refreshGeometry(); +} + +void RevealedPathModule::updateModelMatrix() { + GeomModule::updateModelMatrix(); + +} + +void RevealedPathModule::processReveal(const vector<string>& names, + const vector<float>& surfaces, + const vector<float>& insides, + const vector<float>& center, + const vector<float>& extent, + const vector<float>& color) { + + m_attributesMap["revealed_name"]->setStringsIfChanged(names); + m_attributesMap["revealed_surface"]->setFloatsIfChanged(surfaces); + m_attributesMap["revealed_inside"]->setFloatsIfChanged(insides); + m_attributesMap["revealed_center"]->setFloatsIfChanged(center); + m_attributesMap["revealed_extent"]->setFloatsIfChanged(extent); + m_attributesMap["revealed_color"]->setFloatsIfChanged(color); +} + +void RevealedPathModule::draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& comp){ + + RevealedModule::draw(contextID,prog,uniforms,comp); + + if(m_pathInitialised>0) { + refreshGeometry(); + m_pathInitialised--; + } +} + + +//-------------------------Path Points--------------------------------------- + +void PathPoint::loadPnt(xmlNodePtr node) { + char* value = (char*)xmlGetProp(node, (xmlChar*)"x"); + if(value!=NULL) { + m_point[0]=atof(value); + } + value = (char*)xmlGetProp(node, (xmlChar*)"y"); + if(value!=NULL) { + m_point[1]=atof(value); + } + value = (char*)xmlGetProp(node, (xmlChar*)"z"); + if(value!=NULL) { + m_point[2]=atof(value); + } +} + +xmlNodePtr PathPoint::savePnt(xmlNodePtr parentNode) { + ostringstream oss, oss1, oss2; + xmlNodePtr pntNode = xmlNewChild(parentNode, NULL, BAD_CAST "Point", NULL); + oss<<m_point[0]; + oss1<<m_point[1]; + oss2<<m_point[2]; + xmlNewProp(pntNode, BAD_CAST "x", BAD_CAST oss.str().c_str()); + xmlNewProp(pntNode, BAD_CAST "y", BAD_CAST oss1.str().c_str()); + xmlNewProp(pntNode, BAD_CAST "z", BAD_CAST oss2.str().c_str()); + return pntNode; +} + +PathPointModule::PathPointModule(RevealedPathModule* path): + PathPoint(), Listener(), m_module(NULL) { + m_path=path; + m_listenerType="PathListener"; +} + +PathPointModule::PathPointModule(RevealedPathModule* path, + Module* mod): PathPoint(), Listener() { + m_path=path; + m_listenerType="PathListener"; + m_module=mod; + m_module->getAttribute("absolute_position")->addListener(this); +} + +PathPointModule::~PathPointModule() { + if(m_module) { + m_module->getAttribute("absolute_position")->removeListener(this); + } +} + +void PathPointModule::update(vector<float>& floatValues, + vector<int>& intValues, + vector<bool>& boolValues, + vector<string>& stringValues) { + if(floatValues.size()>=3) { + m_path->refreshGeometry(); + } +} + +void PathPointModule::refreshPos() { + if(m_module) { + const vector<float>& floatValues = m_module + ->getAttribute("absolute_position") + ->getFloats(); + m_absPoint[0]=floatValues[0]; + m_absPoint[1]=floatValues[1]; + m_absPoint[2]=floatValues[2]; + m_absPoint[3]=1; + m_point = inverse(m_path->getModelMat())*m_absPoint; + } + else { + m_module=Reveal::getInstance()->findModule(m_moduleName); + if(m_module) { + m_module->getAttribute("absolute_position")->addListener(this); + } + } +} + +void PathPointModule::loadPnt(xmlNodePtr node) { + char* value = (char*)xmlGetProp(node, (xmlChar*)"module_name"); + if(value!=NULL) { + m_moduleName=string(value); + m_module=Reveal::getInstance()->findModule(m_moduleName); + if(m_module) { + m_module->getAttribute("absolute_position")->addListener(this); + } + } +} + +xmlNodePtr PathPointModule::savePnt(xmlNodePtr parentNode) { + xmlNodePtr pntNode=xmlNewChild(parentNode, NULL, + BAD_CAST"PointModule",NULL); + if(m_module) { + xmlNewProp(pntNode, BAD_CAST"module_name", + BAD_CAST m_module->getFullName().c_str()); + } + return pntNode; +} + diff --git a/src/modules/RevealedPathModule.hpp b/src/modules/RevealedPathModule.hpp new file mode 100644 index 0000000..c815025 --- /dev/null +++ b/src/modules/RevealedPathModule.hpp @@ -0,0 +1,134 @@ +/*************************************************************************** + * RevealedPathModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef RevealedPathModule_h +#define RevealedPathModule_h + +#include "RevealedModule.hpp" + +class PathPoint; +class PathPointModule; + +class RevealedPathModule : public RevealedModule, public ModuleListObserver { + public: + RevealedPathModule(); + virtual ~RevealedPathModule(); + + virtual void load(xmlNodePtr node); + virtual xmlNodePtr save(xmlNodePtr parentNode); + + static void addPointCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedPathModule*>(mod)->addPoint(vals[0], + vals[1], + vals[2]); + } + void addPoint(const float& x, const float& y, const float& z); + static void addModulePointCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedPathModule*>(mod)->addModulePoint(vals[0]); + } + void addModulePoint(const std::string&); + static void removePointCallback(Module* mod) { + dynamic_cast<RevealedPathModule*>(mod)->removePoint(); + } + void removePoint(); + + static void clearPointsCallback(Module* mod) { + dynamic_cast<RevealedPathModule*>(mod)->clearPoints(); + } + void clearPoints(); + static void thicknessCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedPathModule*>(mod)->setThickness(vals[0]); + } + void setThickness(const float& t); + static void edgesCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<RevealedPathModule*>(mod)->setEdges(vals[0]); + } + void setEdges(const int& e); + + void refreshGeometry(); + void updateModelMatrix(); + virtual void processReveal(const std::vector<std::string>&, + const std::vector<float>&,const std::vector<float>&, + const std::vector<float>&,const std::vector<float>&, + const std::vector<float>&); + + virtual void updateModulesList(const std::map<std::string, Module*>&); + + void draw(const int& contextID, + const Reveal::REVIL_PROGRAM& prog, + std::map<Reveal::REVIL_UNIFORM, GLint>& uniforms, + const unsigned int& comp=0); + + protected: + std::vector<PathPoint*> m_points; + std::map<unsigned int, std::vector<glm::vec4> > m_compoVertices; + std::map<unsigned int, glm::mat4> m_compoRots; + std::map<unsigned int, glm::vec4> m_compoLocalSizes; + float m_thickness; + int m_nbEdges; + Geometry* m_pathGeom; + int m_pathInitialised; +}; + +class PathPoint { + public: + PathPoint(){} + PathPoint(glm::vec4 pnt):m_point(pnt){} + virtual ~PathPoint(){} + inline const glm::vec4& getPos(){return m_point;} + inline glm::vec4& editPos(){return m_point;} + virtual void loadPnt(xmlNodePtr node); + virtual xmlNodePtr savePnt(xmlNodePtr parentNode); + virtual void refreshPos(){} + + protected: + glm::vec4 m_point; + glm::vec4 m_absPoint; +}; + +class PathPointModule : public PathPoint, public Listener { + public: + PathPointModule(RevealedPathModule*); + PathPointModule(RevealedPathModule*, Module*); + virtual ~PathPointModule(); + virtual void update(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues); + virtual void loadPnt(xmlNodePtr node); + virtual xmlNodePtr savePnt(xmlNodePtr parentNode); + virtual void refreshPos(); + + protected: + RevealedPathModule* m_path; + Module* m_module; + std::string m_moduleName; +}; + + +#endif + diff --git a/src/modules/RevealedShapeModule.cpp b/src/modules/RevealedShapeModule.cpp new file mode 100644 index 0000000..16440fc --- /dev/null +++ b/src/modules/RevealedShapeModule.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * RevealedShapeModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "RevealedShapeModule.hpp" + +#include "../geoms/Geometry.hpp" + +using namespace std; + +RevealedShapeModule::RevealedShapeModule(): ShapeModule(), RevealedModule(){ + m_type="Shape"; + m_name="shape"; + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + addVisibleFromAttribute(); + addRevealedByAttribute(); + addShapeAttributes(); + addTransformationAttributes(); + addFollowMarkerAttribute(); + addRevealedAttributes(); + addRevealedInsideAttributes(); + addRevealedOutputAttributes(); + /* + vector<string> inside(1, "color_gradient"); + m_attributesMap["inside"]->setStrings(inside); + */ + vector<string> shape(1, "sphere"); + m_attributesMap["shape"]->setStrings(shape); + vector<float> dims(3,200.0); + m_attributesMap["dimensions"]->setFloats(dims); +} + +RevealedShapeModule::~RevealedShapeModule() { + Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentShape]) + ->unregisterModule(this); +} + +void RevealedShapeModule::setShape(const std::string& shape) { + if(m_shapesMap.find(shape)!=m_shapesMap.end()) { + if(m_currentShape.compare("")!=0) { + Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentShape]) + ->unregisterModule(this); + } + m_currentShape=shape; + Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentShape]) + ->registerModule(this); + m_currentGeom=Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentShape]); + m_shapeGeom = m_shapesMap[m_currentShape]; + } +} + diff --git a/src/modules/RevealedShapeModule.hpp b/src/modules/RevealedShapeModule.hpp new file mode 100644 index 0000000..fdfdfc4 --- /dev/null +++ b/src/modules/RevealedShapeModule.hpp @@ -0,0 +1,44 @@ +/*************************************************************************** + * RevealedShapeModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef RevealedShapeModule_h +#define RevealedShapeModule_h + +#include "ShapeModule.hpp" +#include "RevealedModule.hpp" + +class RevealedShapeModule : public ShapeModule, public RevealedModule { + public: + RevealedShapeModule(); + virtual ~RevealedShapeModule(); + void gotAttributeListenersUpdate(Attribute* att) { + RevealedModule::gotAttributeListenersUpdate(att); + } + void setShape(const std::string&); + + protected: +}; + + +#endif + diff --git a/src/modules/RevealedTextModule.cpp b/src/modules/RevealedTextModule.cpp new file mode 100644 index 0000000..c88aa4a --- /dev/null +++ b/src/modules/RevealedTextModule.cpp @@ -0,0 +1,200 @@ +/*************************************************************************** + * RevealedTextModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "RevealedTextModule.hpp" + +#include <iostream> +#include <glm/gtx/quaternion.hpp> + +#include "../Reveal.hpp" + +#include "../geoms/Geometry.hpp" + +using namespace std; + +RevealedTextModule::RevealedTextModule(): ShapeModule(), RevealedModule() { + m_type="Text"; + m_name="text"; + + m_layersNb=1; + int nbBytes = m_texWidth*m_texHeight*m_layersNb*3; + m_layersData = new char[nbBytes]; + m_surf = new Fl_Image_Surface(m_texWidth, m_texHeight); + + m_label = new Fl_Box(0, 0, m_texWidth, m_texHeight, "text"); + m_label->color(FL_BLACK); + m_label->labelcolor(FL_WHITE); + m_label->box(FL_FLAT_BOX); + + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + addVisibleFromAttribute(); + addRevealedByAttribute(); + + addAttribute(new Attribute("text", + Attribute::STRING_ATTRIBUTE, + textCallback, this, 1)); + vector<string> txt(1,"text"); + m_attributesMap["text"]->setStrings(txt); +/* + addAttribute(new Attribute("font_size", + Attribute::INT_ATTRIBUTE, + fontSizeCallback, this, 1)); + addAttribute(new Attribute("dimensions", + Attribute::FLOAT_ATTRIBUTE, + dimensionsCallback, this, 3)); + m_attributesMap["dimensions"]->setFloats(vector<float>(3,100.0)); +*/ + + addShapeAttributes(); + addTransformationAttributes(); + addRevealedAttributes(); + addRevealedOutputAttributes(); + m_localInsideAxes=true; + m_insideDensityAlpha=0; + m_insideGradientAlpha=0; + m_insideTextureAlpha=1.0; + m_insideVisible=true; + m_insideTextureBlend=false; + + + vector<string> shp(1,"frame"); + m_attributesMap["shape"]->setStrings(shp); + + vector<float> dims(3,200.0); + m_attributesMap["dimensions"]->setFloats(dims); + + //set default text +// setText("text"); +} + +RevealedTextModule::~RevealedTextModule() { + Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentShape]) + ->unregisterModule(this); +} + +void RevealedTextModule::setColor(const vector<float>& hsv) { + RevealedModule::setColor(hsv); + m_label->labelcolor(fl_rgb_color(m_color[0]*255, + m_color[1]*255, + m_color[2]*255)); + setText(m_text); +} + +void RevealedTextModule::setFontSize(const int& size) { + m_label->labelsize(size); + setText(m_text); +} + +void RevealedTextModule::setText(const std::string& text) { + m_text=text; + + + //layers in text are separated by | + vector<int> sizes; + string token; + m_tokens.clear(); + istringstream tokenStream(m_text); + while (getline(tokenStream, token, '|')) { + sizes.push_back(0); + + //for each token recreate lines separated by ; + bool done=false; + size_t linePos=-1; + while(!done) { + size_t newPos = token.find(";",linePos+1); + if(newPos!=string::npos) { + token.replace(newPos, size_t(1), "\n"); + sizes.back()=max<int>(sizes.back(), + int(newPos-linePos)); + } + else { + sizes.back()=max<int>(sizes.back(), + int(token.length()-linePos)); + done=true; + } + linePos=newPos; + } + m_tokens.push_back(token); + } + + //recreate layers data + if(int(m_tokens.size())>m_layersNb || !m_layersData) { + if(m_layersData) { + delete [] m_layersData; + } + int nbBytes = m_texWidth*m_texHeight*m_tokens.size()*3; + m_layersData = new char[nbBytes]; + } + m_layersNb=m_tokens.size(); + + //fill data with each part of the string + for(unsigned int d=0; d<m_tokens.size(); ++d) { + //find ; to split in lines + m_label->label(m_tokens[(m_layersNb-1)-d].c_str()); + + m_label->labelsize(float(900) + / float(sizes[(m_layersNb-1)-d]));//FIXME + + m_surf->set_current(); + m_surf->draw(m_label); + m_textImg = m_surf->image(); + Fl_Display_Device::display_device()->set_current(); + for(int i=0; i<m_texWidth; ++i) { + for(int j=0; j<m_texHeight; ++j) { + m_layersData[(d*m_texHeight*m_texWidth+j*m_texWidth+i)*3] + =m_textImg->data()[0][(j*m_textImg->w()+i)*m_textImg->d()]; + m_layersData[(d*m_texHeight*m_texWidth+j*m_texWidth+i)*3+1] + =m_textImg->data()[0][(j*m_textImg->w()+i)*m_textImg->d()+1]; + m_layersData[(d*m_texHeight*m_texWidth+j*m_texWidth+i)*3+2] + =m_textImg->data()[0][(j*m_textImg->w()+i)*m_textImg->d()+2]; + } + } + delete m_textImg; + } + map<int, bool>::iterator itUp = m_insideUpMap.begin(); + for(; itUp!=m_insideUpMap.end(); ++itUp) { + itUp->second=true; + } +} + +void RevealedTextModule::setShape(const std::string& shape) { + if(m_shapesMap.find(shape)!=m_shapesMap.end()) { + if(m_currentShape.compare("")!=0) { + Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentShape]) + ->unregisterModule(this); + } + m_currentShape=shape; + m_shapeGeom=m_shapesMap[m_currentShape]; + Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentShape]) + ->registerModule(this); + m_currentGeom=Reveal::getInstance() + ->getGeom(m_shapesMap[m_currentShape]); + } +} + + diff --git a/src/modules/RevealedTextModule.hpp b/src/modules/RevealedTextModule.hpp new file mode 100644 index 0000000..875e866 --- /dev/null +++ b/src/modules/RevealedTextModule.hpp @@ -0,0 +1,68 @@ +/*************************************************************************** + * RevealedTextModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef RevealedTextModule_h +#define RevealedTextModule_h + +#include "ShapeModule.hpp" +#include "RevealedModule.hpp" +#include <FL/Fl_Box.H> +#include <FL/Fl_Multiline_Output.H> +#include <FL/Fl_Image_Surface.H> + +class RevealedTextModule : public ShapeModule, public RevealedModule { + public: + RevealedTextModule(); + virtual ~RevealedTextModule(); + + static void textCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RevealedTextModule*>(mod)->setText(vals[0]); + } + void setText(const std::string& text); + static void fontSizeCallback(Module* mod, + const std::vector<int>& vals) { + dynamic_cast<RevealedTextModule*>(mod)->setFontSize(vals[0]); + } + void setFontSize(const int& size); + virtual void setColor(const std::vector<float>& hsv); + + static void dimensionsCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<RevealedTextModule*>(mod)->setDimensions(vals[0], + vals[1], + vals[2]); + } + void setShape(const std::string&); + + protected: + std::string m_text; + std::vector<std::string> m_tokens; + Fl_RGB_Image* m_textImg; + Fl_Box* m_label; + Fl_Image_Surface* m_surf; +}; + + +#endif + diff --git a/src/modules/RootSceneGroupModule.cpp b/src/modules/RootSceneGroupModule.cpp new file mode 100644 index 0000000..64b223c --- /dev/null +++ b/src/modules/RootSceneGroupModule.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * RootSceneGroupModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "RootSceneGroupModule.hpp" +#include "RevealedShapeModule.hpp" +#include "RevealedPathModule.hpp" +#include "RevealedTextModule.hpp" +#include "RevealedCutModule.hpp" +#include "RevealedArrowModule.hpp" +#include "RevealedGridModule.hpp" +#include "RevealedModelModule.hpp" +#include "SceneGroupModule.hpp" +#include "../Reveal.hpp" + +using namespace std; + +RootSceneGroupModule::RootSceneGroupModule(): GroupModule() { + m_type="Scene"; + m_name="scene"; +} + +void RootSceneGroupModule::addGroupAttributes() { + addAttribute(new Attribute("add_shape", + Attribute::ACTION_STRING_ATTRIBUTE, + addShapeCallback, this, 1)); + m_attributesMap["add_shape"]->initStrings(vector<string>(1, "shape")); + addAttribute(new Attribute("add_model", + Attribute::ACTION_STRING_ATTRIBUTE, + addModelCallback, this, 1)); + m_attributesMap["add_model"]->initStrings(vector<string>(1, "model")); + addAttribute(new Attribute("add_path", + Attribute::ACTION_STRING_ATTRIBUTE, + addPathCallback, this, 1)); + m_attributesMap["add_path"]->initStrings(vector<string>(1, "path")); + addAttribute(new Attribute("add_text", + Attribute::ACTION_STRING_ATTRIBUTE, + addTextCallback, this, 1)); + m_attributesMap["add_text"]->initStrings(vector<string>(1, "text")); + addAttribute(new Attribute("add_cut", + Attribute::ACTION_STRING_ATTRIBUTE, + addCutCallback, this, 1)); + m_attributesMap["add_cut"]->initStrings(vector<string>(1, "cut")); + addAttribute(new Attribute("add_arrow", + Attribute::ACTION_STRING_ATTRIBUTE, + addArrowCallback, this, 1)); + m_attributesMap["add_arrow"]->initStrings(vector<string>(1, "arrow")); + addAttribute(new Attribute("add_grid", + Attribute::ACTION_STRING_ATTRIBUTE, + addGridCallback, this, 1)); + m_attributesMap["add_grid"]->initStrings(vector<string>(1, "grid")); + addAttribute(new Attribute("add_group", + Attribute::ACTION_STRING_ATTRIBUTE, + addGroupCallback, this, 1)); + m_attributesMap["add_group"]->initStrings(vector<string>(1, "group")); +} + +void RootSceneGroupModule::addShape(const std::string& name) { + RevealedShapeModule* tmp = new RevealedShapeModule(); + addChild(tmp); + tmp->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + +void RootSceneGroupModule::addModel(const std::string& name) { + RevealedModelModule* tmp = new RevealedModelModule(); + addChild(tmp); + tmp->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + +void RootSceneGroupModule::addPath(const std::string& name) { + RevealedPathModule* tmp = new RevealedPathModule(); + addChild(tmp); + tmp->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + +void RootSceneGroupModule::addText(const std::string& name) { + RevealedTextModule* tmp = new RevealedTextModule(); + addChild(tmp); + tmp->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + +void RootSceneGroupModule::addCut(const std::string& name) { + RevealedCutModule* tmp = new RevealedCutModule(); + addChild(tmp); + tmp->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + +void RootSceneGroupModule::addArrow(const std::string& name) { + RevealedArrowModule* tmp = new RevealedArrowModule(); + addChild(tmp); + tmp->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + +void RootSceneGroupModule::addGrid(const std::string& name) { + RevealedGridModule* tmp = new RevealedGridModule(); + addChild(tmp); + tmp->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + +void RootSceneGroupModule::addGroup(const std::string& name) { + SceneGroupModule* tmp = new SceneGroupModule(); + addChild(tmp); + tmp->getAttribute("name")->setStrings(vector<string>(1,name)); + Reveal::getInstance()->refreshModules(); +} + diff --git a/src/modules/RootSceneGroupModule.hpp b/src/modules/RootSceneGroupModule.hpp new file mode 100644 index 0000000..2e47658 --- /dev/null +++ b/src/modules/RootSceneGroupModule.hpp @@ -0,0 +1,77 @@ +/*************************************************************************** + * RootSceneGroupModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef RootSceneGroupModule_h +#define RootSceneGroupModule_h + +#include "GroupModule.hpp" + +class RootSceneGroupModule: public GroupModule { + public: + RootSceneGroupModule(); + virtual ~RootSceneGroupModule(){} + + void addGroupAttributes(); + static void addShapeCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RootSceneGroupModule*>(mod)->addShape(vals[0]); + } + void addShape(const std::string&); + static void addModelCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RootSceneGroupModule*>(mod)->addModel(vals[0]); + } + void addModel(const std::string&); + static void addPathCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RootSceneGroupModule*>(mod)->addPath(vals[0]); + } + void addPath(const std::string&); + static void addTextCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RootSceneGroupModule*>(mod)->addText(vals[0]); + } + void addText(const std::string&); + static void addCutCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RootSceneGroupModule*>(mod)->addCut(vals[0]); + } + void addCut(const std::string&); + static void addArrowCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RootSceneGroupModule*>(mod)->addArrow(vals[0]); + } + void addArrow(const std::string&); + static void addGridCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RootSceneGroupModule*>(mod)->addGrid(vals[0]); + } + void addGrid(const std::string&); + static void addGroupCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<RootSceneGroupModule*>(mod)->addGroup(vals[0]); + } + void addGroup(const std::string&); +}; + +#endif + diff --git a/src/modules/SceneGroupModule.cpp b/src/modules/SceneGroupModule.cpp new file mode 100644 index 0000000..9dd29f1 --- /dev/null +++ b/src/modules/SceneGroupModule.cpp @@ -0,0 +1,40 @@ +/*************************************************************************** + * SceneGroupModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "SceneGroupModule.hpp" + +using namespace std; + +SceneGroupModule::SceneGroupModule(): RootSceneGroupModule() { + m_type="SceneGroup"; + m_name="group"; + addNameAttribute(); + addRemoveAttribute(); + addVisibleAttribute(); + addTransformationAttributes(); + addFollowMarkerAttribute(); + addGroupAttributes(); + vector<float> initPos(3,0); + m_attributesMap["position"]->setFloats(initPos); +} + + diff --git a/src/modules/SceneGroupModule.hpp b/src/modules/SceneGroupModule.hpp new file mode 100644 index 0000000..d3bbf64 --- /dev/null +++ b/src/modules/SceneGroupModule.hpp @@ -0,0 +1,66 @@ +/*************************************************************************** + * SceneGroupModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef SceneGroupModule_h +#define SceneGroupModule_h + +#include "RootSceneGroupModule.hpp" + +class SceneGroupModule: public RootSceneGroupModule { + public: + SceneGroupModule(); + virtual ~SceneGroupModule(){} + + static void nameCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<SceneGroupModule*>(mod)->setName(vals[0]); + } + static void deleteCallback(Module* mod) { + dynamic_cast<SceneGroupModule*>(mod)->deleteModule(); + } + static void visibleCallback(Module* mod, + const std::vector<bool>& vals) { + dynamic_cast<SceneGroupModule*>(mod)->setVisible(vals[0]); + } + static void positionCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<SceneGroupModule*>(mod)->setPosition(vals[0], + vals[1], + vals[2]); + } + static void scaleCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<SceneGroupModule*>(mod)->setScale(vals[0], + vals[1], + vals[2]); + } + static void rotationCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<SceneGroupModule*>(mod)->setRotation(vals[0], + vals[1], + vals[2]); + } +}; + +#endif + + diff --git a/src/modules/ShapeModule.cpp b/src/modules/ShapeModule.cpp new file mode 100644 index 0000000..f287bd9 --- /dev/null +++ b/src/modules/ShapeModule.cpp @@ -0,0 +1,123 @@ +/*************************************************************************** + * ShapeModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "ShapeModule.hpp" + +#include <iostream> + +#include "../Reveal.hpp" +#include <glm/gtx/matrix_decompose.hpp> +#include <glm/gtx/quaternion.hpp> +#include <glm/gtx/euler_angles.hpp> + +using namespace std; +using namespace glm; + +ShapeModule::ShapeModule(): GeomModule() { + m_shapes.push_back("box"); + m_shapesMap["box"]=Reveal::GEOM_BOX; + m_shapes.push_back("sphere"); + m_shapesMap["sphere"]=Reveal::GEOM_SPHERE; + m_shapes.push_back("tube"); + m_shapesMap["tube"]=Reveal::GEOM_TUBE; + m_shapes.push_back("cone"); + m_shapesMap["cone"]=Reveal::GEOM_CONE; + m_shapes.push_back("frame"); + m_shapesMap["frame"]=Reveal::GEOM_FRAME; + m_dimensions=vec3(200.0, 200.0, 200.0); +} + +ShapeModule::~ShapeModule() {} + +void ShapeModule::setDimensions(const float& x, const float& y,const float& z) { + m_dimensions=vec3(x, y, z); + updateModelMatrix(); +} + +void ShapeModule::addShapeAttributes() { + addAttribute(new Attribute("shape", + Attribute::STRING_ATTRIBUTE, + shapeCallback, this, 1)); + m_attributesMap["shape"]->editStringValuesChoices().assign(1, m_shapes); + m_attributesMap["shape"]->initStrings(vector<string>(1, m_shapes[0])); + + addAttribute(new Attribute("dimensions", + Attribute::FLOAT_ATTRIBUTE, + dimensionsCallback, this, 3)); + m_attributesMap["dimensions"]->setFloats(vector<float>(3,100.0)); +} + +void ShapeModule::updateModelMatrix() { + Module::updateModelMatrix(); + mat4 dimMat = scale(m_dimensions); + m_modelMat = m_modelMat * dimMat; + m_invModelMat = inverse(m_modelMat); + vec3 decTrans, decSkew; + quat decRot; + vec4 decPers; + decompose(m_modelMat, m_modelScale, decRot, decTrans, decSkew, decPers); + + //update bounding box as well + vec4 pnts[8]; + vec4 locpnts[8]; + int p=0; + for(float x=-0.5; x<1; x+=1.0) { + for(float y=-0.5; y<1; y+=1.0) { + for(float z=-0.5; z<1; z+=1.0) { + pnts[p] = m_modelMat*vec4(x, y, z, 1.0); + locpnts[p] = vec4(m_modelScale[0]*x, + m_modelScale[1]*y, + m_modelScale[2]*z, + 1.0); + ++p; + } + } + } + m_bbPnts[0]=pnts[0]; + m_bbPnts[1]=pnts[0]; + for(p=1; p<8; ++p) { + for(int c=0; c<3;++c) { + m_bbPnts[0][c]=std::min<float>(pnts[p][c], m_bbPnts[0][c]); + m_bbPnts[1][c]=std::max<float>(pnts[p][c], m_bbPnts[1][c]); + } + } + + /* + //store min and size (max-min) + m_bboxSizes[0] = bboxMax-m_bboxMins[0]; + m_bboxLocalSizes[0] = bboxLocMax-m_bboxLocalMin[0]; + + if(m_localInsideAxes) { + m_bboxRots[0] = glm::inverse(toMat4(decRot)); + } + else { + m_bboxRots[0] = mat4(1.0); + } + */ + + + for(auto &up : m_boundingRectUpdate) { + up.second=true; + } +} + diff --git a/src/modules/ShapeModule.hpp b/src/modules/ShapeModule.hpp new file mode 100644 index 0000000..edd564a --- /dev/null +++ b/src/modules/ShapeModule.hpp @@ -0,0 +1,59 @@ +/*************************************************************************** + * ShapeModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef ShapeModule_h +#define ShapeModule_h + +#include "GeomModule.hpp" + +class ShapeModule : public virtual GeomModule { + public: + ShapeModule(); + virtual ~ShapeModule(); + + static void shapeCallback(Module* mod, + const std::vector<std::string>& vals) { + dynamic_cast<ShapeModule*>(mod)->setShape(vals[0]); + } + virtual void setShape(const std::string&){} + static void dimensionsCallback(Module* mod, + const std::vector<float>& vals) { + dynamic_cast<ShapeModule*>(mod)->setDimensions(vals[0], + vals[1], + vals[2]); + } + void setDimensions(const float&, const float&, const float&); + + virtual void updateModelMatrix(); + void addShapeAttributes(); + + protected: + std::vector<std::string> m_shapes; + std::map<std::string, Reveal::GEOM_ID> m_shapesMap; + glm::vec3 m_dimensions; + std::string m_currentShape; +}; + + +#endif + diff --git a/src/modules/SpaceModule.cpp b/src/modules/SpaceModule.cpp new file mode 100644 index 0000000..a1729de --- /dev/null +++ b/src/modules/SpaceModule.cpp @@ -0,0 +1,315 @@ +/*************************************************************************** + * SpaceModule.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/*//////////// +Calibration heavily relies on code from : +https://github.com/Kj1/ofxSpaceKinectCalibration +*///////////////////// + +#include "SpaceModule.hpp" + +#include <iostream> + +#include "../Reveal.hpp" +#include "DepthCamModule.hpp" +#include "ProjectorModule.hpp" +#include "DepthShapeModule.hpp" +#include "DepthMeshModule.hpp" + +#include "../geoms/BoxGeometry.hpp" +#include "../geoms/CamGeometry.hpp" +#include "../geoms/QuadGeometry.hpp" +#include "../geoms/SphereGeometry.hpp" +#include "../geoms/TubeGeometry.hpp" +#include "../geoms/ConeGeometry.hpp" + +using namespace std; + +SpaceModule::SpaceModule(): DepthGroupModule() { + m_type="Space"; + m_name="space"; + m_space=this; + + /* + addAttribute(new Attribute("name", + Attribute::STRING_ATTRIBUTE, + nameCallback, this, 1, Attribute::LOCAL)); + m_attributesMap["name"]->setStrings(vector<string>(1, m_name)); + addAttribute(new Attribute("add_projector", + Attribute::ACTION_ATTRIBUTE, + addProjCallback, this, Attribute::LOCAL)); + addAttribute(new Attribute("add_depth_group", + Attribute::ACTION_STRING_ATTRIBUTE, + addDepthGroupCallback, this, 1)); + addAttribute(new Attribute("add_depth_camera", + Attribute::ACTION_ATTRIBUTE, + addCamCallback, this, Attribute::LOCAL)); + addAttribute(new Attribute("add_depth_shape", + Attribute::ACTION_STRING_ATTRIBUTE, + addDepthShapeCallback, this, 1)); + m_attributesMap["add_depth_shape"]->initStrings(vector<string>(1,"shape")); + addAttribute(new Attribute("add_depth_mesh", + Attribute::ACTION_STRING_ATTRIBUTE, + addDepthMeshCallback, this, 1)); + m_attributesMap["add_depth_mesh"]->initStrings(vector<string>(1,"mesh")); +*/ + //create all depth geometries + m_geomsMap[Reveal::GEOM_BOX] = new BoxGeometry(); + m_geomsMap[Reveal::GEOM_QUAD] = new QuadGeometry(); + m_geomsMap[Reveal::GEOM_CAM1280] = new CamGeometry(1280, 960); + m_geomsMap[Reveal::GEOM_CAM640] = new CamGeometry(640, 480); + m_geomsMap[Reveal::GEOM_CAM320] = new CamGeometry(320, 240); + m_geomsMap[Reveal::GEOM_SPHERE] = new SphereGeometry(); + m_geomsMap[Reveal::GEOM_TUBE] = new TubeGeometry(); + m_geomsMap[Reveal::GEOM_CONE] = new ConeGeometry(); + map<Reveal::GEOM_ID, Geometry*>::iterator itGeom = m_geomsMap.begin(); + for(; itGeom!=m_geomsMap.end(); ++itGeom) { + itGeom->second->setGeomID(itGeom->first); + m_geoms.push_back(itGeom->second); + } + m_attributesMap["name"]->setStrings(vector<string>(1, m_name)); +} + +SpaceModule::~SpaceModule() {} + +void SpaceModule::draw() { + vector<ProjectorModule*>::iterator itProj=m_projModules.begin(); + for(; itProj!=m_projModules.end(); ++itProj) { + (*itProj)->draw(); + } +} + +void SpaceModule::removeProj(ProjectorModule* proj) { + vector<ProjectorModule*>::iterator itProj=m_projModules.begin(); + for(; itProj!=m_projModules.end();) { + if((*itProj)->getFullName().compare(proj->getFullName())==0) { + itProj = m_projModules.erase(itProj); + } + else { + itProj++; + } + } + removeChild(proj); + refreshDepthCamList(); + refreshProjList(); +} + +void SpaceModule::removeCam(DepthCamModule* cam) { + vector<DepthCamModule*>::iterator itCam=m_depthCamModules.begin(); + for(; itCam!=m_depthCamModules.end();) { + if((*itCam)->getFullName().compare(cam->getFullName())==0) { + itCam = m_depthCamModules.erase(itCam); + } + else { + itCam++; + } + } + removeDepthModule(cam); + removeChild(cam); + refreshDepthCamList(); + refreshProjList(); +} + +void SpaceModule::refreshDepthCamList() { + vector<ProjectorModule*>::iterator itProj=m_projModules.begin(); + for(; itProj!=m_projModules.end(); ++itProj) { + (*itProj)->refreshDepthCamList(m_depthCamModules); + } +} + +void SpaceModule::refreshProjList() { + vector<DepthCamModule*>::iterator itCam=m_depthCamModules.begin(); + for(; itCam!=m_depthCamModules.end(); ++itCam) { + (*itCam)->refreshProjList(m_projModules); + } +} + +void SpaceModule::addChild(Module* mod) { + if(mod->getType().compare("Projector")==0) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + proj->setSpace(this); + } + else { + DepthModule* dep = dynamic_cast<DepthModule*>(mod); + dep->setSpace(this); + } + DepthGroupModule::addChild(mod); +} + + +DepthCamModule* SpaceModule::getDepthCamModule(const std::string& name) { + DepthCamModule* cam=NULL; + vector<DepthCamModule*>::const_iterator itCam=m_depthCamModules.begin(); + for(; itCam!=m_depthCamModules.end(); ++itCam) { + if((*itCam)->getName().compare(name)==0) { + cam=(*itCam); + } + } + return cam; +} + +void SpaceModule::addSpaceModule(Module* mod) { + if(mod->getType().compare("Projector")==0) { + ProjectorModule* proj = static_cast<ProjectorModule*>(mod); + m_projModules.push_back(proj); + proj->setSpace(this); + } + else if(mod->getType().compare("DepthCam")==0) { + DepthCamModule* cam = dynamic_cast<DepthCamModule*>(mod); + m_depthCamModules.push_back(cam); + m_depthModules.push_back(cam); + cam->setSpace(this); + } + else if(mod->getType().compare("DepthShape")==0) { + DepthShapeModule* sha = dynamic_cast<DepthShapeModule*>(mod); + m_depthShapeModules.push_back(sha); + m_depthModules.push_back(sha); + sha->setSpace(this); + } + else if(mod->getType().compare("DepthMesh")==0) { + DepthMeshModule* mes = dynamic_cast<DepthMeshModule*>(mod); + m_depthMeshModules.push_back(mes); + m_depthModules.push_back(mes); + mes->setSpace(this); + } + else if(mod->getType().compare("DepthGroup")==0) { + DepthGroupModule* gro = dynamic_cast<DepthGroupModule*>(mod); + gro->setSpace(this); + } + + + updateDepthModules(); + refreshDepthCamList(); + refreshProjList(); +} + +void SpaceModule::removeDepthModule(DepthModule* mod) { + vector<DepthModule*>::iterator itMod = m_depthModules.begin(); + for(; itMod!=m_depthModules.end();) { + if((*itMod)->getDepthID()==mod->getDepthID()) { + itMod=m_depthModules.erase(itMod); + } + else { + ++itMod; + } + } +} + +void SpaceModule::updateDepthModules() { + unsigned int id=1; + //assign depth ids + m_depthIDsModules.clear(); + vector<DepthModule*>::iterator itMod = m_depthModules.begin(); + for(; itMod!=m_depthModules.end(); ++itMod) { + (*itMod)->setDepthID(id); + for(int s=0; s<(*itMod)->getNbSubDepthIDs(); ++s, ++id) { + m_depthIDsModules[id]=*itMod; + } + } + //reorder things : depths then projs + m_children.clear(); + vector<DepthModule*>::iterator itDe = m_depthModules.begin(); + for(; itDe!=m_depthModules.end(); ++itDe) { + m_children.push_back(*itDe); + } + vector<ProjectorModule*>::iterator itProj = m_projModules.begin(); + for(; itProj!=m_projModules.end(); ++itProj) { + m_children.push_back(*itProj); + } +} + +void SpaceModule::getVisibleFromList(vector<string>& modVec, + map<string, int>& modMap) { + int spaceMask = 1 << modVec.size(); + modVec.push_back(m_name); + modMap[modVec.back()] = spaceMask; + + vector<ProjectorModule*>::iterator itProj=m_projModules.begin(); + for(; itProj!=m_projModules.end(); ++itProj) { + int projMask = (1 << modVec.size()); + modVec.push_back((*itProj)->getName()); + modMap[modVec.back()] = projMask; + (*itProj)->setVisibilityMask(projMask | spaceMask | 1); + } +} + +void SpaceModule::registerGeom(Geometry* geom) { + if(geom->getGeomID()<0) { + Reveal::GEOM_ID newID = Reveal::GEOM_MODEL; + while(m_geomsMap.find(newID)!=m_geomsMap.end()) { + newID = Reveal::GEOM_ID(int(newID)+1); + } + geom->setGeomID(newID); + m_geomsMap[newID]=geom; + m_geoms.push_back(geom); + } +} + +void SpaceModule::unregisterGeom(Geometry* geom) { + m_geomsMap.erase(geom->getGeomID()); + vector<Geometry*>::iterator itGeom = m_geoms.begin(); + for(; itGeom!=m_geoms.end(); ) { + if((*itGeom)->getGeomID()==geom->getGeomID()) { + itGeom = m_geoms.erase(itGeom); + } + else { + ++itGeom; + } + } +} + +//SPACES +void SpacesModule::addSpace() { + SpaceModule* proj = new SpaceModule(); + addChild(proj); + m_spaces.push_back(proj); + Reveal::getInstance()->refreshModules(); +} + +void SpacesModule::load(xmlNodePtr node) { + Module::load(node); + xmlNodePtr modsNode; + for(modsNode=node->children; modsNode; modsNode=modsNode->next){ + if(modsNode->type == XML_ELEMENT_NODE && + !xmlStrcmp(modsNode->name, (const xmlChar *) "Modules")) { + xmlNodePtr modNode; + for(modNode=modsNode->children; modNode; modNode=modNode->next){ + if(modNode->type == XML_ELEMENT_NODE) { + if(!xmlStrcmp(modNode->name, (const xmlChar *)"Preview")) { + m_children[0]->load(modNode); + } + else { + string typeStr((char*) modNode->name); + Module* mod = + Reveal::getInstance()->createModule(typeStr); + if(mod) { + addChild(mod); + mod->load(modNode); + } + } + } + } + } + } +} + + diff --git a/src/modules/SpaceModule.hpp b/src/modules/SpaceModule.hpp new file mode 100644 index 0000000..765793e --- /dev/null +++ b/src/modules/SpaceModule.hpp @@ -0,0 +1,111 @@ +/*************************************************************************** + * SpaceModule.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef SpaceModule_h +#define SpaceModule_h + +#include "DepthGroupModule.hpp" +#include <iostream> + +class Geometry; + +class SpaceModule : public DepthGroupModule { + public: + SpaceModule(); + virtual ~SpaceModule(); + + virtual void draw(); + + void removeProj(ProjectorModule*); + + void removeCam(DepthCamModule*); + inline const unsigned int getNbDepthCamModules() { + return m_depthCamModules.size(); + } + inline DepthCamModule* getDepthCamModule(const unsigned int& mod) { + if(mod<m_depthCamModules.size()) { + return m_depthCamModules[mod]; + } + return NULL; + } + DepthCamModule* getDepthCamModule(const std::string& name); + + void addSpaceModule(Module*); + void removeDepthModule(DepthModule*); + void updateDepthModules(); + DepthModule* getDepthModuleFromID(const unsigned int& id){ + if(m_depthIDsModules.find(id)!=m_depthIDsModules.end()) { + return m_depthIDsModules[id]; + } + return NULL; + } + unsigned int getNbDepthModulesFromID(){return m_depthIDsModules.size();} + + virtual void addChild(Module* mod); + void refreshDepthCamList(); + void refreshProjList(); + + const std::vector<Geometry*>& getGeoms(){return m_geoms;} + Geometry* getGeom(const Reveal::GEOM_ID& geomStr) { + return m_geomsMap[geomStr]; + } + void registerGeom(Geometry* geom); + void unregisterGeom(Geometry* geom); + virtual void getVisibleFromList(std::vector<std::string>& modVec, + std::map<std::string, int>& modMap); + + private: + std::vector<DepthCamModule*> m_depthCamModules; + std::vector<DepthShapeModule*> m_depthShapeModules; + std::vector<DepthMeshModule*> m_depthMeshModules; + std::vector<ProjectorModule*> m_projModules; + std::vector<DepthModule*> m_depthModules; + std::map<unsigned int, DepthModule*> m_depthIDsModules; + std::map<Reveal::GEOM_ID, Geometry*> m_geomsMap; + std::vector<Geometry*> m_geoms; +}; + +class SpacesModule: public GroupModule { + public: + SpacesModule(): GroupModule() { + m_type="Spaces"; + m_name="spaces"; + addAttribute(new Attribute("add_space", + Attribute::ACTION_ATTRIBUTE, + addSpaceCallback, this, + Attribute::LOCAL)); + } + static void addSpaceCallback(Module* mod) { + dynamic_cast<SpacesModule*>(mod)->addSpace(); + } + void addSpace(); + void updateVisibleFrom(std::vector<std::string>& modVec, + std::map<std::string, int>& modMap); + virtual void load(xmlNodePtr node); + const std::vector<SpaceModule*>& getSpaces(){return m_spaces;} + private: + std::vector<SpaceModule*> m_spaces; +}; + +#endif + diff --git a/src/osc/OscListener.cpp b/src/osc/OscListener.cpp new file mode 100644 index 0000000..ec4529d --- /dev/null +++ b/src/osc/OscListener.cpp @@ -0,0 +1,188 @@ +/*************************************************************************** + * OscListener.cpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "OscListener.hpp" +#include <iostream> +#include <sstream> +#include "OscManager.hpp" +#include "../modules/Attribute.hpp" + +using namespace std; + +OscListener::OscListener(const std::string& adPort):Listener() { + m_listenerType="OscListener"; + m_parameters.push_back(""); + m_parametersValues.push_back(vector<string>()); + m_parameters.push_back(adPort); + m_parametersValues.push_back(vector<string>()); + + vector<string> vals; + vals.push_back("grouped"); + vals.push_back("separated"); + m_parameters.push_back(vals[0]); + m_parametersValues.push_back(vals); + m_attribute=NULL; + m_grouped=true; + updateNet(); +} + +OscListener::OscListener():Listener() { + m_listenerType="OscListener"; + m_parameters.push_back(""); + m_parametersValues.push_back(vector<string>()); + m_parameters.push_back("127.0.0.1:7000"); + m_parametersValues.push_back(vector<string>()); + + vector<string> vals; + vals.push_back("grouped"); + vals.push_back("separated"); + m_parameters.push_back(vals[0]); + m_parametersValues.push_back(vals); + m_attribute=NULL; + m_grouped=true; + updateNet(); + + //FIXME, define listener attributes with different types +} + +void OscListener::setAttribute(Attribute* att) { + m_attribute=att; + updateNet(); +} + +void OscListener::setParameters(const std::vector<std::string>& params) { + Listener::setParameters(params); + updateNet(); +} + +void OscListener::updateNet() { + if(m_parameters[0].size()==0) { + if(m_attribute!=NULL) { + m_parameters[0]=m_attribute->getFullName(); + } + } + m_url = m_parameters[0]; + size_t sep = m_parameters[1].find(':'); + if(sep!=string::npos) { + istringstream iss; + iss.str(m_parameters[1].substr(sep+1)); + iss >> m_port; + m_adress=m_parameters[1].substr(0, sep); + } + if(m_parameters[2].compare("grouped")==0) { + m_grouped=true; + } + else { + m_grouped=false; + } +} + +void OscListener::update(vector<float>& floatValues, + vector<int>& intValues, + vector<bool>& boolValues, + vector<string>& stringValues) { + //FIXME get OutputManager -> selected output + OscManager* osc = OscManager::getInstance(); + if(m_grouped) { + //if(floatValues.size()<10) { + osc->sendMessage(m_parameters[1], + m_adress, + m_port, + m_url, + floatValues, + intValues, + boolValues, + stringValues); + //} + /*else { //FIXME + osc->sendBlobMessage(m_parameters[1], + m_adress, + m_port, + m_url, + floatValues); + }*/ + } + else { + int vi = 1; + for(float& v : floatValues) { + ostringstream oss; + oss << vi; + osc->sendMessage(m_parameters[1], + m_adress, + m_port, + m_url+"/"+oss.str(), + vector<float>(1, v), + intValues, + boolValues, + stringValues); + vi++; + } + + vi=1; + for(int& i : intValues) { + ostringstream oss; + oss << vi; + osc->sendMessage(m_parameters[1], + m_adress, + m_port, + m_url+"/"+oss.str(), + floatValues, + vector<int>(1, i), + boolValues, + stringValues); + vi++; + } + + vi=1; + for(bool b : boolValues) { + ostringstream oss; + oss << vi; + osc->sendMessage(m_parameters[1], + m_adress, + m_port, + m_url+"/"+oss.str(), + floatValues, + intValues, + vector<bool>(1, b), + stringValues); + vi++; + } + + vi=1; + for(string& s : stringValues) { + ostringstream oss; + oss << vi; + osc->sendMessage(m_parameters[1], + m_adress, + m_port, + m_url+"/"+oss.str(), + floatValues, + intValues, + boolValues, + vector<string>(1, s)); + vi++; + } + } +} + + + diff --git a/src/osc/OscListener.hpp b/src/osc/OscListener.hpp new file mode 100644 index 0000000..1f94a27 --- /dev/null +++ b/src/osc/OscListener.hpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * OscListener.hpp + * Part of Reveal + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef OscListener_h +#define OscListener_h + +#include "../modules/Listener.hpp" + +class OscListener: public Listener { + public: + OscListener(); + OscListener(const std::string& adPort); + virtual ~OscListener(){} + virtual void setAttribute(Attribute* att); + virtual void update(std::vector<float>& floatValues, + std::vector<int>& intValues, + std::vector<bool>& boolValues, + std::vector<std::string>& stringValues); + void updateNet(); + virtual void setParameters(const std::vector<std::string>& par); + + protected: + std::string m_adress; + unsigned int m_port; + std::string m_url; + bool m_grouped; +}; + +#endif diff --git a/src/osc/OscManager.cpp b/src/osc/OscManager.cpp new file mode 100644 index 0000000..8cf1e26 --- /dev/null +++ b/src/osc/OscManager.cpp @@ -0,0 +1,264 @@ +/*************************************************************************** + * OscManager.cpp + * Part of OscManager + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "OscManager.hpp" + +#include <iostream> +#include <pthread.h> + +#include "../Reveal.hpp" +#include "OscListener.hpp" + +using namespace std; + +OscManager* OscManager::getInstance() { + static OscManager rev; + return &rev; +} + +OscManager::OscManager(): osc::OscPacketListener() {} +OscManager::~OscManager() {} + +void* oscThreadFunction(void* pvParam) { + OscManager *pThis=(OscManager*)pvParam; + pThis->m_socket->Run(); + return 0; +} + +void OscManager::init() { + //initialize osc input + try{ + m_socket = new UdpListeningReceiveSocket( + IpEndpointName(IpEndpointName::ANY_ADDRESS, 8327), + (osc::OscPacketListener*)this); + m_thread = new std::thread(oscThreadFunction, this); + } + catch(const exception& e) { + DEBUG("Error in the OscManager "<<e.what()); + } +} + +void OscManager::update() { + //retrieve osc messages + if(m_msgLock.try_lock()) { + while(m_messages.size()>0) { + OscMessage firstMess = m_messages.front(); + m_messages.pop_front(); + OscMessage *mess = &firstMess; + + std::string name = mess->m_name; + if(Reveal::getInstance()->getDebugOSC()) { + cout<<"OSC: "<<name<<endl; + } + //try attributes first then modules + Attribute *att = Reveal::getInstance()->findAttribute(name); + if(att) { + if(att->getAccessibility()==Attribute::GLOBAL + || att->getAccessibility()==Attribute::OUTPUT) { + + //test first register / unregister listeners + if(mess->m_strValues.size()>0 + && mess->m_strValues[0].compare("register")==0) { + att->addListener(new OscListener(mess->m_strValues[1])); + } + else if(mess->m_strValues.size()>0 + && mess->m_strValues[0].compare("unregister")==0) { + //FIXME + } + else //test set attributes + if(att->getType()==Attribute::FLOAT_ATTRIBUTE + || att->getType()==Attribute::ACTION_FLOAT_ATTRIBUTE) { + if(mess->m_floatValues.size()>0) { + att->setFloats(mess->m_floatValues); + } + else if(mess->m_intValues.size()>0) { + att->setInts(mess->m_intValues); + } + } + else if((att->getType()==Attribute::INT_ATTRIBUTE + || att->getType()==Attribute::ACTION_INT_ATTRIBUTE) + && mess->m_intValues.size()>0) { + att->setInts(mess->m_intValues); + } + else if(att->getType()==Attribute::BOOL_ATTRIBUTE + && mess->m_boolValues.size()>0) { + att->setBools(mess->m_boolValues); + } + else if((att->getType()==Attribute::STRING_ATTRIBUTE + || att->getType()==Attribute::ACTION_STRING_ATTRIBUTE) + && mess->m_strValues.size()>0) { + att->setStrings(mess->m_strValues); + } + else if((att->getType()==Attribute::FILE_OPEN_ATTRIBUTE + || att->getType()==Attribute::FOLDER_OPEN_ATTRIBUTE) + && mess->m_strValues.size()>0) { + att->setFile(mess->m_strValues[0]); + } + else if(att->getType()==Attribute::ACTION_ATTRIBUTE){ + att->setAction(); + } + } + } + } + m_msgLock.unlock(); + } + + //send created bundles + /* + vector<OscStream*>::iterator itStream = m_streamsVec.begin(); + for(; itStream!=m_streamsVec.end(); ++itStream) { + if((*itStream)->m_bundleStarted) { + try { + *((*itStream)->m_stream) << osc::EndBundle; + UdpSocket socket; + socket.SetEnableBroadcast(true); + socket.SendTo(IpEndpointName((*itStream)->m_adress.c_str(), + (*itStream)->m_port), + (*itStream)->m_stream->Data(), + (*itStream)->m_stream->Size()); + } + catch(const exception& e) { + cout<<"Error in the osc output "<<e.what()<<endl; + } + } + (*itStream)->m_bundleStarted=false; + }*/ +} + +void OscManager::stop() { + +} + +void OscManager::ProcessMessage(const osc::ReceivedMessage& mess, + const IpEndpointName& remoteEndpoint) { + //OscMessage *newMessage = new OscMessage(); + OscMessage newMessage; + try { + newMessage.m_name=std::string(mess.AddressPattern()); + osc::ReceivedMessage::const_iterator itArg = mess.ArgumentsBegin(); + for(; itArg!=mess.ArgumentsEnd(); ++itArg) { + if(itArg->IsFloat()) { + newMessage.m_floatValues.push_back(itArg->AsFloatUnchecked()); + newMessage.m_boolValues.push_back((itArg->AsFloatUnchecked())); + } + else if( itArg->IsInt32() ) { + newMessage.m_intValues.push_back( + (float)(itArg->AsInt32Unchecked())); + newMessage.m_boolValues.push_back((itArg->AsInt32Unchecked())); + } + else if( itArg->IsString() ) { + newMessage.m_strValues.push_back( + std::string(itArg->AsString())); + } + } + } + catch(const exception& e) { + cout<<"Exception when receiving osc message "<<e.what()<<endl; + } + + m_msgLock.lock(); + m_messages.push_back(newMessage); + m_msgLock.unlock(); + /* + if(jack_ringbuffer_write_space(m_messagesRingBuffer)>=m_messageSize + && received) { + jack_ringbuffer_write(m_messagesRingBuffer, + (char*)(&newMessage), + m_messageSize); + } + else { + delete newMessage; + }*/ +} + +void OscManager::sendMessage(const string& id, + const string& adress, + const int& port, + const string& name, + const vector<float>& fValues, + const vector<int>& iValues, + const vector<bool>& bValues, + const vector<string>& sValues) { + //create the stream to the destination if it does not exist + if(m_streamsMap.find(id)==m_streamsMap.end()) { + OscStream* newStream = new OscStream(); + newStream->m_id=id; + newStream->m_adress=adress; + newStream->m_port=port; + newStream->m_stream=new osc::OutboundPacketStream(newStream->m_buffer, + IP_MTU_SIZE); + newStream->m_bundleStarted=false; + m_streamsMap[id]=newStream; + m_streamsVec.push_back(newStream); + } + + OscStream* stream = m_streamsMap[id]; + + //start a bundle if it is not started + if(!stream->m_bundleStarted) { + stream->m_stream->Clear(); + *(stream->m_stream) << osc::BeginBundleImmediate; + stream->m_bundleStarted=true; + } + + //add a message + try { + *(stream->m_stream) << osc::BeginMessage(name.c_str()); + vector<string>::const_iterator itS; + for(itS=sValues.begin(); itS!=sValues.end(); ++itS) { + *(stream->m_stream)<<(*itS).c_str(); + } + vector<float>::const_iterator itF; + for(itF=fValues.begin(); itF!=fValues.end(); ++itF) { + *(stream->m_stream)<<(float)(*itF); + } + vector<int>::const_iterator itI; + for(itI=iValues.begin(); itI!=iValues.end(); ++itI) { + *(stream->m_stream)<<(int)(*itI); + } + vector<bool>::const_iterator itB; + for(itB=bValues.begin(); itB!=bValues.end(); ++itB) { + *(stream->m_stream)<<(bool)(*itB); + } + *(stream->m_stream) << osc::EndMessage; + } + catch(const exception& e) { + DEBUG("Error in the osc output "<<e.what()); + } + //FIXME :not efficient, but bundles become too big because of voxels/histo + //FIXME: change voxels/histo to blobs or test bundle size + try { + *(stream->m_stream) << osc::EndBundle; + UdpSocket socket; + socket.SetEnableBroadcast(true); + socket.SendTo(IpEndpointName(stream->m_adress.c_str(), + stream->m_port), + stream->m_stream->Data(), + stream->m_stream->Size()); + stream->m_bundleStarted=false; + } + catch(const exception& e) { + cout<<"Error in the osc output "<<e.what()<<endl; + } +} + diff --git a/src/osc/OscManager.hpp b/src/osc/OscManager.hpp new file mode 100644 index 0000000..bf63855 --- /dev/null +++ b/src/osc/OscManager.hpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * OscManager.hpp + * Part of OscManager + * 2015- Florent Berthaut + * hitmuri.net + ****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#ifndef OscManager_h +#define OscManager_h + +#include <string> +#include <vector> +#include <deque> +#include <map> +#include <thread> +#include <mutex> +#include "oscPack/ip/IpEndpointName.h" +#include "oscPack/osc/OscReceivedElements.h" +#include "oscPack/osc/OscOutboundPacketStream.h" +#include "oscPack/ip/UdpSocket.h" +#include "oscPack/osc/OscPacketListener.h" + +#define IP_MTU_SIZE 10000 + +struct OscMessage { + std::string m_name; + std::vector<float> m_floatValues; + std::vector<int> m_intValues; + std::vector<bool> m_boolValues; + std::vector<std::string> m_strValues; +}; + +struct OscStream { + std::string m_id; + std::string m_adress; + int m_port; + char m_buffer[IP_MTU_SIZE]; + osc::OutboundPacketStream* m_stream; + bool m_bundleStarted; +}; + +class OscManager : public osc::OscPacketListener { + public: + static OscManager* getInstance(); + ~OscManager(); + + void init(); + int run(); + void update(); + void stop(); + virtual void ProcessMessage(const osc::ReceivedMessage& m, + const IpEndpointName& remoteEndpoint); + + void sendMessage(const std::string& id, + const std::string& adress, + const int& port, + const std::string& name, + const std::vector<float>& fValues, + const std::vector<int>& iValues, + const std::vector<bool>& bValues, + const std::vector<std::string>& sValues); + + public: + UdpListeningReceiveSocket* m_socket; + + private: + OscManager(); + + private: + size_t m_messageSize; + char m_buffer[IP_MTU_SIZE]; + std::deque<OscMessage> m_messages; + std::map<std::string, OscStream*> m_streamsMap; + std::vector<OscStream*> m_streamsVec; + std::thread* m_thread; + std::mutex m_msgLock; + +}; + +#endif + diff --git a/src/osc/oscPack/ip/IpEndpointName.cpp b/src/osc/oscPack/ip/IpEndpointName.cpp new file mode 100644 index 0000000..556da3a --- /dev/null +++ b/src/osc/oscPack/ip/IpEndpointName.cpp @@ -0,0 +1,88 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#include "IpEndpointName.h" + +#include <cstdio> + +#include "NetworkingUtils.h" + + +unsigned long IpEndpointName::GetHostByName( const char *s ) +{ + return ::GetHostByName(s); +} + + +void IpEndpointName::AddressAsString( char *s ) const +{ + if( address == ANY_ADDRESS ){ + std::sprintf( s, "<any>" ); + }else{ + std::sprintf( s, "%d.%d.%d.%d", + (int)((address >> 24) & 0xFF), + (int)((address >> 16) & 0xFF), + (int)((address >> 8) & 0xFF), + (int)(address & 0xFF) ); + } +} + + +void IpEndpointName::AddressAndPortAsString( char *s ) const +{ + if( port == ANY_PORT ){ + if( address == ANY_ADDRESS ){ + std::sprintf( s, "<any>:<any>" ); + }else{ + std::sprintf( s, "%d.%d.%d.%d:<any>", + (int)((address >> 24) & 0xFF), + (int)((address >> 16) & 0xFF), + (int)((address >> 8) & 0xFF), + (int)(address & 0xFF) ); + } + }else{ + if( address == ANY_ADDRESS ){ + std::sprintf( s, "<any>:%d", port ); + }else{ + std::sprintf( s, "%d.%d.%d.%d:%d", + (int)((address >> 24) & 0xFF), + (int)((address >> 16) & 0xFF), + (int)((address >> 8) & 0xFF), + (int)(address & 0xFF), + (int)port ); + } + } +} diff --git a/src/osc/oscPack/ip/IpEndpointName.h b/src/osc/oscPack/ip/IpEndpointName.h new file mode 100644 index 0000000..4b3159a --- /dev/null +++ b/src/osc/oscPack/ip/IpEndpointName.h @@ -0,0 +1,83 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_IPENDPOINTNAME_H +#define INCLUDED_OSCPACK_IPENDPOINTNAME_H + + +class IpEndpointName{ + static unsigned long GetHostByName( const char *s ); +public: + static const unsigned long ANY_ADDRESS = 0xFFFFFFFF; + static const int ANY_PORT = -1; + + IpEndpointName() + : address( ANY_ADDRESS ), port( ANY_PORT ) {} + IpEndpointName( int port_ ) + : address( ANY_ADDRESS ), port( port_ ) {} + IpEndpointName( unsigned long ipAddress_, int port_ ) + : address( ipAddress_ ), port( port_ ) {} + IpEndpointName( const char *addressName, int port_=ANY_PORT ) + : address( GetHostByName( addressName ) ) + , port( port_ ) {} + IpEndpointName( int addressA, int addressB, int addressC, int addressD, int port_=ANY_PORT ) + : address( ( (addressA << 24) | (addressB << 16) | (addressC << 8) | addressD ) ) + , port( port_ ) {} + + // address and port are maintained in host byte order here + unsigned long address; + int port; + + bool IsMulticastAddress() const { return ((address >> 24) & 0xFF) >= 224 && ((address >> 24) & 0xFF) <= 239; } + + enum { ADDRESS_STRING_LENGTH=17 }; + void AddressAsString( char *s ) const; + + enum { ADDRESS_AND_PORT_STRING_LENGTH=23}; + void AddressAndPortAsString( char *s ) const; +}; + +inline bool operator==( const IpEndpointName& lhs, const IpEndpointName& rhs ) +{ + return (lhs.address == rhs.address && lhs.port == rhs.port ); +} + +inline bool operator!=( const IpEndpointName& lhs, const IpEndpointName& rhs ) +{ + return !(lhs == rhs); +} + +#endif /* INCLUDED_OSCPACK_IPENDPOINTNAME_H */ diff --git a/src/osc/oscPack/ip/NetworkingUtils.h b/src/osc/oscPack/ip/NetworkingUtils.h new file mode 100644 index 0000000..516e9d2 --- /dev/null +++ b/src/osc/oscPack/ip/NetworkingUtils.h @@ -0,0 +1,56 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_NETWORKINGUTILS_H +#define INCLUDED_OSCPACK_NETWORKINGUTILS_H + + +// in general NetworkInitializer is only used internally, but if you're +// application creates multiple sockets from different threads at runtime you +// should instantiate one of these in main just to make sure the networking +// layer is initialized. +class NetworkInitializer{ +public: + NetworkInitializer(); + ~NetworkInitializer(); +}; + + +// return ip address of host name in host byte order +unsigned long GetHostByName( const char *name ); + + +#endif /* INCLUDED_OSCPACK_NETWORKINGUTILS_H */ diff --git a/src/osc/oscPack/ip/PacketListener.h b/src/osc/oscPack/ip/PacketListener.h new file mode 100644 index 0000000..2a8cf63 --- /dev/null +++ b/src/osc/oscPack/ip/PacketListener.h @@ -0,0 +1,50 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_PACKETLISTENER_H +#define INCLUDED_OSCPACK_PACKETLISTENER_H + + +class IpEndpointName; + +class PacketListener{ +public: + virtual ~PacketListener() {} + virtual void ProcessPacket( const char *data, int size, + const IpEndpointName& remoteEndpoint ) = 0; +}; + +#endif /* INCLUDED_OSCPACK_PACKETLISTENER_H */ diff --git a/src/osc/oscPack/ip/TimerListener.h b/src/osc/oscPack/ip/TimerListener.h new file mode 100644 index 0000000..61e262b --- /dev/null +++ b/src/osc/oscPack/ip/TimerListener.h @@ -0,0 +1,47 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_TIMERLISTENER_H +#define INCLUDED_OSCPACK_TIMERLISTENER_H + + +class TimerListener{ +public: + virtual ~TimerListener() {} + virtual void TimerExpired() = 0; +}; + +#endif /* INCLUDED_OSCPACK_TIMERLISTENER_H */ diff --git a/src/osc/oscPack/ip/UdpSocket.h b/src/osc/oscPack/ip/UdpSocket.h new file mode 100644 index 0000000..8bebb27 --- /dev/null +++ b/src/osc/oscPack/ip/UdpSocket.h @@ -0,0 +1,176 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_UDPSOCKET_H +#define INCLUDED_OSCPACK_UDPSOCKET_H + +#include <cstring> // size_t + +#include "NetworkingUtils.h" +#include "IpEndpointName.h" + + +class PacketListener; +class TimerListener; + +class UdpSocket; + +class SocketReceiveMultiplexer{ + class Implementation; + Implementation *impl_; + + friend class UdpSocket; + +public: + SocketReceiveMultiplexer(); + ~SocketReceiveMultiplexer(); + + // only call the attach/detach methods _before_ calling Run + + // only one listener per socket, each socket at most once + void AttachSocketListener( UdpSocket *socket, PacketListener *listener ); + void DetachSocketListener( UdpSocket *socket, PacketListener *listener ); + + void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener ); + void AttachPeriodicTimerListener( + int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener ); + void DetachPeriodicTimerListener( TimerListener *listener ); + + void Run(); // loop and block processing messages indefinitely + void RunUntilSigInt(); + void Break(); // call this from a listener to exit once the listener returns + void AsynchronousBreak(); // call this from another thread or signal handler to exit the Run() state +}; + + +class UdpSocket{ + class Implementation; + Implementation *impl_; + + friend class SocketReceiveMultiplexer::Implementation; + +public: + + // Ctor throws std::runtime_error if there's a problem + // initializing the socket. + UdpSocket(); + virtual ~UdpSocket(); + + // Enable broadcast addresses (e.g. x.x.x.255) + // Sets SO_BROADCAST socket option. + void SetEnableBroadcast( bool enableBroadcast ); + + // Enable multiple listeners for a single port on same + // network interface* + // Sets SO_REUSEADDR (also SO_REUSEPORT on OS X). + // [*] The exact behavior of SO_REUSEADDR and + // SO_REUSEPORT is undefined for some common cases + // and may have drastically different behavior on different + // operating systems. + void SetAllowReuse( bool allowReuse ); + + + // The socket is created in an unbound, unconnected state + // such a socket can only be used to send to an arbitrary + // address using SendTo(). To use Send() you need to first + // connect to a remote endpoint using Connect(). To use + // ReceiveFrom you need to first bind to a local endpoint + // using Bind(). + + // Retrieve the local endpoint name when sending to 'to' + IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const; + + // Connect to a remote endpoint which is used as the target + // for calls to Send() + void Connect( const IpEndpointName& remoteEndpoint ); + void Send( const char *data, std::size_t size ); + void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size ); + + + // Bind a local endpoint to receive incoming data. Endpoint + // can be 'any' for the system to choose an endpoint + void Bind( const IpEndpointName& localEndpoint ); + bool IsBound() const; + + std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size ); +}; + + +// convenience classes for transmitting and receiving +// they just call Connect and/or Bind in the ctor. +// note that you can still use a receive socket +// for transmitting etc + +class UdpTransmitSocket : public UdpSocket{ +public: + UdpTransmitSocket( const IpEndpointName& remoteEndpoint ) + { Connect( remoteEndpoint ); } +}; + + +class UdpReceiveSocket : public UdpSocket{ +public: + UdpReceiveSocket( const IpEndpointName& localEndpoint ) + { Bind( localEndpoint ); } +}; + + +// UdpListeningReceiveSocket provides a simple way to bind one listener +// to a single socket without having to manually set up a SocketReceiveMultiplexer + +class UdpListeningReceiveSocket : public UdpSocket{ + SocketReceiveMultiplexer mux_; + PacketListener *listener_; +public: + UdpListeningReceiveSocket( const IpEndpointName& localEndpoint, PacketListener *listener ) + : listener_( listener ) + { + Bind( localEndpoint ); + mux_.AttachSocketListener( this, listener_ ); + } + + ~UdpListeningReceiveSocket() + { mux_.DetachSocketListener( this, listener_ ); } + + // see SocketReceiveMultiplexer above for the behaviour of these methods... + void Run() { mux_.Run(); } + void RunUntilSigInt() { mux_.RunUntilSigInt(); } + void Break() { mux_.Break(); } + void AsynchronousBreak() { mux_.AsynchronousBreak(); } +}; + + +#endif /* INCLUDED_OSCPACK_UDPSOCKET_H */ diff --git a/src/osc/oscPack/ip/posix/NetworkingUtils.cpp b/src/osc/oscPack/ip/posix/NetworkingUtils.cpp new file mode 100644 index 0000000..941507f --- /dev/null +++ b/src/osc/oscPack/ip/posix/NetworkingUtils.cpp @@ -0,0 +1,64 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#include "../NetworkingUtils.h" + +#include <netdb.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include <cstring> + + + +NetworkInitializer::NetworkInitializer() {} + +NetworkInitializer::~NetworkInitializer() {} + + +unsigned long GetHostByName( const char *name ) +{ + unsigned long result = 0; + + struct hostent *h = gethostbyname( name ); + if( h ){ + struct in_addr a; + std::memcpy( &a, h->h_addr_list[0], h->h_length ); + result = ntohl(a.s_addr); + } + + return result; +} diff --git a/src/osc/oscPack/ip/posix/UdpSocket.cpp b/src/osc/oscPack/ip/posix/UdpSocket.cpp new file mode 100644 index 0000000..fc04585 --- /dev/null +++ b/src/osc/oscPack/ip/posix/UdpSocket.cpp @@ -0,0 +1,605 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#include "../UdpSocket.h" + +#include <pthread.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <netinet/in.h> // for sockaddr_in + +#include <signal.h> +#include <math.h> +#include <errno.h> +#include <string.h> +#include <iostream> + +#include <algorithm> +#include <cassert> +#include <cstring> // for memset +#include <stdexcept> +#include <vector> + +#include "../PacketListener.h" +#include "../TimerListener.h" + + +#if defined(__APPLE__) && !defined(_SOCKLEN_T) +// pre system 10.3 didn't have socklen_t +typedef ssize_t socklen_t; +#endif + + +static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint ) +{ + std::memset( (char *)&sockAddr, 0, sizeof(sockAddr ) ); + sockAddr.sin_family = AF_INET; + + sockAddr.sin_addr.s_addr = + (endpoint.address == IpEndpointName::ANY_ADDRESS) + ? INADDR_ANY + : htonl( endpoint.address ); + + sockAddr.sin_port = + (endpoint.port == IpEndpointName::ANY_PORT) + ? 0 + : htons( endpoint.port ); +} + + +static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr ) +{ + return IpEndpointName( + (sockAddr.sin_addr.s_addr == INADDR_ANY) + ? IpEndpointName::ANY_ADDRESS + : ntohl( sockAddr.sin_addr.s_addr ), + (sockAddr.sin_port == 0) + ? IpEndpointName::ANY_PORT + : ntohs( sockAddr.sin_port ) + ); +} + + +class UdpSocket::Implementation{ + bool isBound_; + bool isConnected_; + + int socket_; + struct sockaddr_in connectedAddr_; + struct sockaddr_in sendToAddr_; + +public: + + Implementation() + : isBound_( false ) + , isConnected_( false ) + , socket_( -1 ) + { + if( (socket_ = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 ){ + throw std::runtime_error("unable to create udp socket\n"); + } + + std::memset( &sendToAddr_, 0, sizeof(sendToAddr_) ); + sendToAddr_.sin_family = AF_INET; + } + + ~Implementation() + { + if (socket_ != -1) close(socket_); + } + + void SetEnableBroadcast( bool enableBroadcast ) + { + int broadcast = (enableBroadcast) ? 1 : 0; // int on posix + if(setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, + &broadcast, sizeof(broadcast))<0) { + std::cout<<"Error setting broadcast"<<std::endl; + } + } + + void SetAllowReuse( bool allowReuse ) + { + int reuseAddr = (allowReuse) ? 1 : 0; // int on posix + setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)); + +#ifdef __APPLE__ + // needed also for OS X - enable multiple listeners for a single port on same network interface + int reusePort = (allowReuse) ? 1 : 0; // int on posix + setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &reusePort, sizeof(reusePort)); +#endif + } + + IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const + { + assert( isBound_ ); + + // first connect the socket to the remote server + + struct sockaddr_in connectSockAddr; + SockaddrFromIpEndpointName( connectSockAddr, remoteEndpoint ); + + if (connect(socket_, (struct sockaddr *)&connectSockAddr, sizeof(connectSockAddr)) < 0) { + throw std::runtime_error("unable to connect udp socket\n"); + } + + // get the address + + struct sockaddr_in sockAddr; + std::memset( (char *)&sockAddr, 0, sizeof(sockAddr ) ); + socklen_t length = sizeof(sockAddr); + if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) { + throw std::runtime_error("unable to getsockname\n"); + } + + if( isConnected_ ){ + // reconnect to the connected address + + if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) { + throw std::runtime_error("unable to connect udp socket\n"); + } + + }else{ + // unconnect from the remote address + + struct sockaddr_in unconnectSockAddr; + std::memset( (char *)&unconnectSockAddr, 0, sizeof(unconnectSockAddr ) ); + unconnectSockAddr.sin_family = AF_UNSPEC; + // address fields are zero + int connectResult = connect(socket_, (struct sockaddr *)&unconnectSockAddr, sizeof(unconnectSockAddr)); + if ( connectResult < 0 && errno != EAFNOSUPPORT ) { + throw std::runtime_error("unable to un-connect udp socket\n"); + } + } + + return IpEndpointNameFromSockaddr( sockAddr ); + } + + void Connect( const IpEndpointName& remoteEndpoint ) + { + SockaddrFromIpEndpointName( connectedAddr_, remoteEndpoint ); + + if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) { + throw std::runtime_error("unable to connect udp socket\n"); + } + + isConnected_ = true; + } + + void Send( const char *data, std::size_t size ) + { + assert( isConnected_ ); + send( socket_, data, size, 0 ); + } + + void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size ) + { + sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address ); + sendToAddr_.sin_port = htons( remoteEndpoint.port ); + + sendto( socket_, data, size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) ); + } + + void Bind( const IpEndpointName& localEndpoint ) + { + struct sockaddr_in bindSockAddr; + SockaddrFromIpEndpointName( bindSockAddr, localEndpoint ); + + if (bind(socket_, (struct sockaddr *)&bindSockAddr, sizeof(bindSockAddr)) < 0) { + throw std::runtime_error("unable to bind udp socket\n"); + } + + isBound_ = true; + } + + bool IsBound() const { return isBound_; } + + std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size ) + { + assert( isBound_ ); + + struct sockaddr_in fromAddr; + socklen_t fromAddrLen = sizeof(fromAddr); + + ssize_t result = recvfrom(socket_, data, size, MSG_DONTWAIT, + (struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen); + if( result < 0 ) + return 0; + + remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr); + remoteEndpoint.port = ntohs(fromAddr.sin_port); + + return (std::size_t)result; + } + + int Socket() { return socket_; } +}; + +UdpSocket::UdpSocket() +{ + impl_ = new Implementation(); +} + +UdpSocket::~UdpSocket() +{ + delete impl_; +} + +void UdpSocket::SetEnableBroadcast( bool enableBroadcast ) +{ + impl_->SetEnableBroadcast( enableBroadcast ); +} + +void UdpSocket::SetAllowReuse( bool allowReuse ) +{ + impl_->SetAllowReuse( allowReuse ); +} + +IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const +{ + return impl_->LocalEndpointFor( remoteEndpoint ); +} + +void UdpSocket::Connect( const IpEndpointName& remoteEndpoint ) +{ + impl_->Connect( remoteEndpoint ); +} + +void UdpSocket::Send( const char *data, std::size_t size ) +{ + impl_->Send( data, size ); +} + +void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size ) +{ + impl_->SendTo( remoteEndpoint, data, size ); +} + +void UdpSocket::Bind( const IpEndpointName& localEndpoint ) +{ + impl_->Bind( localEndpoint ); +} + +bool UdpSocket::IsBound() const +{ + return impl_->IsBound(); +} + +std::size_t UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size ) +{ + return impl_->ReceiveFrom( remoteEndpoint, data, size ); +} + + +struct AttachedTimerListener{ + AttachedTimerListener( int id, int p, TimerListener *tl ) + : initialDelayMs( id ) + , periodMs( p ) + , listener( tl ) {} + int initialDelayMs; + int periodMs; + TimerListener *listener; +}; + + +static bool CompareScheduledTimerCalls( + const std::pair< double, AttachedTimerListener > & lhs, const std::pair< double, AttachedTimerListener > & rhs ) +{ + return lhs.first < rhs.first; +} + + +SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0; + +extern "C" /*static*/ void InterruptSignalHandler( int ); +/*static*/ void InterruptSignalHandler( int ) +{ + multiplexerInstanceToAbortWithSigInt_->AsynchronousBreak(); + signal( SIGINT, SIG_DFL ); +} + + +class SocketReceiveMultiplexer::Implementation{ + std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_; + std::vector< AttachedTimerListener > timerListeners_; + + volatile bool break_; + int breakPipe_[2]; // [0] is the reader descriptor and [1] the writer + + double GetCurrentTimeMs() const + { + struct timeval t; + + gettimeofday( &t, 0 ); + + return ((double)t.tv_sec*1000.) + ((double)t.tv_usec / 1000.); + } + +public: + Implementation() + { + if( pipe(breakPipe_) != 0 ) + throw std::runtime_error( "creation of asynchronous break pipes failed\n" ); + } + + ~Implementation() + { + close( breakPipe_[0] ); + close( breakPipe_[1] ); + } + + void AttachSocketListener( UdpSocket *socket, PacketListener *listener ) + { + assert( std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ) == socketListeners_.end() ); + // we don't check that the same socket has been added multiple times, even though this is an error + socketListeners_.push_back( std::make_pair( listener, socket ) ); + } + + void DetachSocketListener( UdpSocket *socket, PacketListener *listener ) + { + std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = + std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ); + assert( i != socketListeners_.end() ); + + socketListeners_.erase( i ); + } + + void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener ) + { + timerListeners_.push_back( AttachedTimerListener( periodMilliseconds, periodMilliseconds, listener ) ); + } + + void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener ) + { + timerListeners_.push_back( AttachedTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ) ); + } + + void DetachPeriodicTimerListener( TimerListener *listener ) + { + std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin(); + while( i != timerListeners_.end() ){ + if( i->listener == listener ) + break; + ++i; + } + + assert( i != timerListeners_.end() ); + + timerListeners_.erase( i ); + } + + void Run() + { + break_ = false; + char *data = 0; + + try{ + + // configure the master fd_set for select() + + fd_set masterfds, tempfds; + FD_ZERO( &masterfds ); + FD_ZERO( &tempfds ); + + // in addition to listening to the inbound sockets we + // also listen to the asynchronous break pipe, so that AsynchronousBreak() + // can break us out of select() from another thread. + FD_SET( breakPipe_[0], &masterfds ); + int fdmax = breakPipe_[0]; + + for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin(); + i != socketListeners_.end(); ++i ){ + + if( fdmax < i->second->impl_->Socket() ) + fdmax = i->second->impl_->Socket(); + FD_SET( i->second->impl_->Socket(), &masterfds ); + } + + + // configure the timer queue + double currentTimeMs = GetCurrentTimeMs(); + + // expiry time ms, listener + std::vector< std::pair< double, AttachedTimerListener > > timerQueue_; + for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin(); + i != timerListeners_.end(); ++i ) + timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) ); + std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls ); + + const int MAX_BUFFER_SIZE = 4098; + data = new char[ MAX_BUFFER_SIZE ]; + IpEndpointName remoteEndpoint; + + struct timeval timeout; + + while( !break_ ){ + tempfds = masterfds; + + struct timeval *timeoutPtr = 0; + if( !timerQueue_.empty() ){ + double timeoutMs = timerQueue_.front().first - GetCurrentTimeMs(); + if( timeoutMs < 0 ) + timeoutMs = 0; + + long timoutSecondsPart = (long)(timeoutMs * .001); + timeout.tv_sec = (time_t)timoutSecondsPart; + // 1000000 microseconds in a second + timeout.tv_usec = (suseconds_t)((timeoutMs - (timoutSecondsPart * 1000)) * 1000); + timeoutPtr = &timeout; + } + + if( select( fdmax + 1, &tempfds, 0, 0, timeoutPtr ) < 0 ){ + if( break_ ){ + break; + }else if( errno == EINTR ){ + // on returning an error, select() doesn't clear tempfds. + // so tempfds would remain all set, which would cause read( breakPipe_[0]... + // below to block indefinitely. therefore if select returns EINTR we restart + // the while() loop instead of continuing on to below. + continue; + }else{ + throw std::runtime_error("select failed\n"); + } + } + + if( FD_ISSET( breakPipe_[0], &tempfds ) ){ + // clear pending data from the asynchronous break pipe + char c; + read( breakPipe_[0], &c, 1 ); + } + + if( break_ ) + break; + + for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin(); + i != socketListeners_.end(); ++i ){ + + if( FD_ISSET( i->second->impl_->Socket(), &tempfds ) ){ + + std::size_t size = i->second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE ); + if( size > 0 ){ + i->first->ProcessPacket( data, (int)size, remoteEndpoint ); + if( break_ ) + break; + } + } + } + + // execute any expired timers + currentTimeMs = GetCurrentTimeMs(); + bool resort = false; + for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin(); + i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){ + + i->second.listener->TimerExpired(); + if( break_ ) + break; + + i->first += i->second.periodMs; + resort = true; + } + if( resort ) + std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls ); + } + + delete [] data; + }catch(...){ + if( data ) + delete [] data; + throw; + } + } + + void Break() + { + break_ = true; + } + + void AsynchronousBreak() + { + break_ = true; + + // Send a termination message to the asynchronous break pipe, so select() will return + write( breakPipe_[1], "!", 1 ); + } +}; + + + +SocketReceiveMultiplexer::SocketReceiveMultiplexer() +{ + impl_ = new Implementation(); +} + +SocketReceiveMultiplexer::~SocketReceiveMultiplexer() +{ + delete impl_; +} + +void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener ) +{ + impl_->AttachSocketListener( socket, listener ); +} + +void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener ) +{ + impl_->DetachSocketListener( socket, listener ); +} + +void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener ) +{ + impl_->AttachPeriodicTimerListener( periodMilliseconds, listener ); +} + +void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener ) +{ + impl_->AttachPeriodicTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ); +} + +void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener ) +{ + impl_->DetachPeriodicTimerListener( listener ); +} + +void SocketReceiveMultiplexer::Run() +{ + impl_->Run(); +} + +void SocketReceiveMultiplexer::RunUntilSigInt() +{ + assert( multiplexerInstanceToAbortWithSigInt_ == 0 ); /* at present we support only one multiplexer instance running until sig int */ + multiplexerInstanceToAbortWithSigInt_ = this; + signal( SIGINT, InterruptSignalHandler ); + impl_->Run(); + signal( SIGINT, SIG_DFL ); + multiplexerInstanceToAbortWithSigInt_ = 0; +} + +void SocketReceiveMultiplexer::Break() +{ + impl_->Break(); +} + +void SocketReceiveMultiplexer::AsynchronousBreak() +{ + impl_->AsynchronousBreak(); +} + diff --git a/src/osc/oscPack/ip/win32/NetworkingUtils.cpp b/src/osc/oscPack/ip/win32/NetworkingUtils.cpp new file mode 100644 index 0000000..a3f4f6a --- /dev/null +++ b/src/osc/oscPack/ip/win32/NetworkingUtils.cpp @@ -0,0 +1,95 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#include "../NetworkingUtils.h" + +#include <winsock2.h> // this must come first to prevent errors with MSVC7 +#include <windows.h> + +#include <cstring> + + +static LONG initCount_ = 0; +static bool winsockInitialized_ = false; + +NetworkInitializer::NetworkInitializer() +{ + if( InterlockedIncrement( &initCount_ ) == 1 ){ + // there is a race condition here if one thread tries to access + // the library while another is still initializing it. + // i can't think of an easy way to fix it so i'm telling you here + // incase you need to init the library from two threads at once. + // this is why the header file advises to instantiate one of these + // in main() so that the initialization happens globally + + // initialize winsock + WSAData wsaData; + int nCode = WSAStartup(MAKEWORD(1, 1), &wsaData); + if( nCode != 0 ){ + //std::cout << "WSAStartup() failed with error code " << nCode << "\n"; + }else{ + winsockInitialized_ = true; + } + } +} + + +NetworkInitializer::~NetworkInitializer() +{ + if( InterlockedDecrement( &initCount_ ) == 0 ){ + if( winsockInitialized_ ){ + WSACleanup(); + winsockInitialized_ = false; + } + } +} + + +unsigned long GetHostByName( const char *name ) +{ + NetworkInitializer networkInitializer; + + unsigned long result = 0; + + struct hostent *h = gethostbyname( name ); + if( h ){ + struct in_addr a; + std::memcpy( &a, h->h_addr_list[0], h->h_length ); + result = ntohl(a.s_addr); + } + + return result; +} diff --git a/src/osc/oscPack/ip/win32/UdpSocket.cpp b/src/osc/oscPack/ip/win32/UdpSocket.cpp new file mode 100644 index 0000000..9967c0a --- /dev/null +++ b/src/osc/oscPack/ip/win32/UdpSocket.cpp @@ -0,0 +1,571 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ + +#include <winsock2.h> // this must come first to prevent errors with MSVC7 +#include <windows.h> +#include <mmsystem.h> // for timeGetTime() + +#ifndef WINCE +#include <signal.h> +#endif + +#include <algorithm> +#include <cassert> +#include <cstring> // for memset +#include <stdexcept> +#include <vector> + +#include "../UdpSocket.h" // usually I'd include the module header first + // but this is causing conflicts with BCB4 due to + // std::size_t usage. + +#include "../NetworkingUtils.h" +#include "../PacketListener.h" +#include "../TimerListener.h" + + +typedef int socklen_t; + + +static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint ) +{ + std::memset( (char *)&sockAddr, 0, sizeof(sockAddr ) ); + sockAddr.sin_family = AF_INET; + + sockAddr.sin_addr.s_addr = + (endpoint.address == IpEndpointName::ANY_ADDRESS) + ? INADDR_ANY + : htonl( endpoint.address ); + + sockAddr.sin_port = + (endpoint.port == IpEndpointName::ANY_PORT) + ? (short)0 + : htons( (short)endpoint.port ); +} + + +static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr ) +{ + return IpEndpointName( + (sockAddr.sin_addr.s_addr == INADDR_ANY) + ? IpEndpointName::ANY_ADDRESS + : ntohl( sockAddr.sin_addr.s_addr ), + (sockAddr.sin_port == 0) + ? IpEndpointName::ANY_PORT + : ntohs( sockAddr.sin_port ) + ); +} + + +class UdpSocket::Implementation{ + NetworkInitializer networkInitializer_; + + bool isBound_; + bool isConnected_; + + SOCKET socket_; + struct sockaddr_in connectedAddr_; + struct sockaddr_in sendToAddr_; + +public: + + Implementation() + : isBound_( false ) + , isConnected_( false ) + , socket_( INVALID_SOCKET ) + { + if( (socket_ = socket( AF_INET, SOCK_DGRAM, 0 )) == INVALID_SOCKET ){ + throw std::runtime_error("unable to create udp socket\n"); + } + + std::memset( &sendToAddr_, 0, sizeof(sendToAddr_) ); + sendToAddr_.sin_family = AF_INET; + } + + ~Implementation() + { + if (socket_ != INVALID_SOCKET) closesocket(socket_); + } + + void SetEnableBroadcast( bool enableBroadcast ) + { + char broadcast = (char)((enableBroadcast) ? 1 : 0); // char on win32 + setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)); + } + + void SetAllowReuse( bool allowReuse ) + { + // Note: SO_REUSEADDR is non-deterministic for listening sockets on Win32. See MSDN article: + // "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" + // http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx + + char reuseAddr = (char)((allowReuse) ? 1 : 0); // char on win32 + setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)); + } + + IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const + { + assert( isBound_ ); + + // first connect the socket to the remote server + + struct sockaddr_in connectSockAddr; + SockaddrFromIpEndpointName( connectSockAddr, remoteEndpoint ); + + if (connect(socket_, (struct sockaddr *)&connectSockAddr, sizeof(connectSockAddr)) < 0) { + throw std::runtime_error("unable to connect udp socket\n"); + } + + // get the address + + struct sockaddr_in sockAddr; + std::memset( (char *)&sockAddr, 0, sizeof(sockAddr ) ); + socklen_t length = sizeof(sockAddr); + if (getsockname(socket_, (struct sockaddr *)&sockAddr, &length) < 0) { + throw std::runtime_error("unable to getsockname\n"); + } + + if( isConnected_ ){ + // reconnect to the connected address + + if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) { + throw std::runtime_error("unable to connect udp socket\n"); + } + + }else{ + // unconnect from the remote address + + struct sockaddr_in unconnectSockAddr; + SockaddrFromIpEndpointName( unconnectSockAddr, IpEndpointName() ); + + if( connect(socket_, (struct sockaddr *)&unconnectSockAddr, sizeof(unconnectSockAddr)) < 0 + && WSAGetLastError() != WSAEADDRNOTAVAIL ){ + throw std::runtime_error("unable to un-connect udp socket\n"); + } + } + + return IpEndpointNameFromSockaddr( sockAddr ); + } + + void Connect( const IpEndpointName& remoteEndpoint ) + { + SockaddrFromIpEndpointName( connectedAddr_, remoteEndpoint ); + + if (connect(socket_, (struct sockaddr *)&connectedAddr_, sizeof(connectedAddr_)) < 0) { + throw std::runtime_error("unable to connect udp socket\n"); + } + + isConnected_ = true; + } + + void Send( const char *data, std::size_t size ) + { + assert( isConnected_ ); + + send( socket_, data, (int)size, 0 ); + } + + void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size ) + { + sendToAddr_.sin_addr.s_addr = htonl( remoteEndpoint.address ); + sendToAddr_.sin_port = htons( (short)remoteEndpoint.port ); + + sendto( socket_, data, (int)size, 0, (sockaddr*)&sendToAddr_, sizeof(sendToAddr_) ); + } + + void Bind( const IpEndpointName& localEndpoint ) + { + struct sockaddr_in bindSockAddr; + SockaddrFromIpEndpointName( bindSockAddr, localEndpoint ); + + if (bind(socket_, (struct sockaddr *)&bindSockAddr, sizeof(bindSockAddr)) < 0) { + throw std::runtime_error("unable to bind udp socket\n"); + } + + isBound_ = true; + } + + bool IsBound() const { return isBound_; } + + std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size ) + { + assert( isBound_ ); + + struct sockaddr_in fromAddr; + socklen_t fromAddrLen = sizeof(fromAddr); + + int result = recvfrom(socket_, data, (int)size, 0, + (struct sockaddr *) &fromAddr, (socklen_t*)&fromAddrLen); + if( result < 0 ) + return 0; + + remoteEndpoint.address = ntohl(fromAddr.sin_addr.s_addr); + remoteEndpoint.port = ntohs(fromAddr.sin_port); + + return result; + } + + SOCKET& Socket() { return socket_; } +}; + +UdpSocket::UdpSocket() +{ + impl_ = new Implementation(); +} + +UdpSocket::~UdpSocket() +{ + delete impl_; +} + +void UdpSocket::SetEnableBroadcast( bool enableBroadcast ) +{ + impl_->SetEnableBroadcast( enableBroadcast ); +} + +void UdpSocket::SetAllowReuse( bool allowReuse ) +{ + impl_->SetAllowReuse( allowReuse ); +} + +IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const +{ + return impl_->LocalEndpointFor( remoteEndpoint ); +} + +void UdpSocket::Connect( const IpEndpointName& remoteEndpoint ) +{ + impl_->Connect( remoteEndpoint ); +} + +void UdpSocket::Send( const char *data, std::size_t size ) +{ + impl_->Send( data, size ); +} + +void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size ) +{ + impl_->SendTo( remoteEndpoint, data, size ); +} + +void UdpSocket::Bind( const IpEndpointName& localEndpoint ) +{ + impl_->Bind( localEndpoint ); +} + +bool UdpSocket::IsBound() const +{ + return impl_->IsBound(); +} + +std::size_t UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size ) +{ + return impl_->ReceiveFrom( remoteEndpoint, data, size ); +} + + +struct AttachedTimerListener{ + AttachedTimerListener( int id, int p, TimerListener *tl ) + : initialDelayMs( id ) + , periodMs( p ) + , listener( tl ) {} + int initialDelayMs; + int periodMs; + TimerListener *listener; +}; + + +static bool CompareScheduledTimerCalls( + const std::pair< double, AttachedTimerListener > & lhs, const std::pair< double, AttachedTimerListener > & rhs ) +{ + return lhs.first < rhs.first; +} + + +SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0; + +extern "C" /*static*/ void InterruptSignalHandler( int ); +/*static*/ void InterruptSignalHandler( int ) +{ + multiplexerInstanceToAbortWithSigInt_->AsynchronousBreak(); +#ifndef WINCE + signal( SIGINT, SIG_DFL ); +#endif +} + + +class SocketReceiveMultiplexer::Implementation{ + NetworkInitializer networkInitializer_; + + std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_; + std::vector< AttachedTimerListener > timerListeners_; + + volatile bool break_; + HANDLE breakEvent_; + + double GetCurrentTimeMs() const + { +#ifndef WINCE + return timeGetTime(); // FIXME: bad choice if you want to run for more than 40 days +#else + return 0; +#endif + } + +public: + Implementation() + { + breakEvent_ = CreateEvent( NULL, FALSE, FALSE, NULL ); + } + + ~Implementation() + { + CloseHandle( breakEvent_ ); + } + + void AttachSocketListener( UdpSocket *socket, PacketListener *listener ) + { + assert( std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ) == socketListeners_.end() ); + // we don't check that the same socket has been added multiple times, even though this is an error + socketListeners_.push_back( std::make_pair( listener, socket ) ); + } + + void DetachSocketListener( UdpSocket *socket, PacketListener *listener ) + { + std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = + std::find( socketListeners_.begin(), socketListeners_.end(), std::make_pair(listener, socket) ); + assert( i != socketListeners_.end() ); + + socketListeners_.erase( i ); + } + + void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener ) + { + timerListeners_.push_back( AttachedTimerListener( periodMilliseconds, periodMilliseconds, listener ) ); + } + + void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener ) + { + timerListeners_.push_back( AttachedTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ) ); + } + + void DetachPeriodicTimerListener( TimerListener *listener ) + { + std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin(); + while( i != timerListeners_.end() ){ + if( i->listener == listener ) + break; + ++i; + } + + assert( i != timerListeners_.end() ); + + timerListeners_.erase( i ); + } + + void Run() + { + break_ = false; + + // prepare the window events which we use to wake up on incoming data + // we use this instead of select() primarily to support the AsyncBreak() + // mechanism. + + std::vector<HANDLE> events( socketListeners_.size() + 1, 0 ); + int j=0; + for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin(); + i != socketListeners_.end(); ++i, ++j ){ + + HANDLE event = CreateEvent( NULL, FALSE, FALSE, NULL ); + WSAEventSelect( i->second->impl_->Socket(), event, FD_READ ); // note that this makes the socket non-blocking which is why we can safely call RecieveFrom() on all sockets below + events[j] = event; + } + + + events[ socketListeners_.size() ] = breakEvent_; // last event in the collection is the break event + + + // configure the timer queue + double currentTimeMs = GetCurrentTimeMs(); + + // expiry time ms, listener + std::vector< std::pair< double, AttachedTimerListener > > timerQueue_; + for( std::vector< AttachedTimerListener >::iterator i = timerListeners_.begin(); + i != timerListeners_.end(); ++i ) + timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) ); + std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls ); + + const int MAX_BUFFER_SIZE = 4098; + char *data = new char[ MAX_BUFFER_SIZE ]; + IpEndpointName remoteEndpoint; + + while( !break_ ){ + + double currentTimeMs = GetCurrentTimeMs(); + + DWORD waitTime = INFINITE; + if( !timerQueue_.empty() ){ + + waitTime = (DWORD)( timerQueue_.front().first >= currentTimeMs + ? timerQueue_.front().first - currentTimeMs + : 0 ); + } + + DWORD waitResult = WaitForMultipleObjects( (DWORD)socketListeners_.size() + 1, &events[0], FALSE, waitTime ); + if( break_ ) + break; + + if( waitResult != WAIT_TIMEOUT ){ + for( int i = waitResult - WAIT_OBJECT_0; i < (int)socketListeners_.size(); ++i ){ + std::size_t size = socketListeners_[i].second->ReceiveFrom( remoteEndpoint, data, MAX_BUFFER_SIZE ); + if( size > 0 ){ + socketListeners_[i].first->ProcessPacket( data, (int)size, remoteEndpoint ); + if( break_ ) + break; + } + } + } + + // execute any expired timers + currentTimeMs = GetCurrentTimeMs(); + bool resort = false; + for( std::vector< std::pair< double, AttachedTimerListener > >::iterator i = timerQueue_.begin(); + i != timerQueue_.end() && i->first <= currentTimeMs; ++i ){ + + i->second.listener->TimerExpired(); + if( break_ ) + break; + + i->first += i->second.periodMs; + resort = true; + } + if( resort ) + std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls ); + } + + delete [] data; + + // free events + j = 0; + for( std::vector< std::pair< PacketListener*, UdpSocket* > >::iterator i = socketListeners_.begin(); + i != socketListeners_.end(); ++i, ++j ){ + + WSAEventSelect( i->second->impl_->Socket(), events[j], 0 ); // remove association between socket and event + CloseHandle( events[j] ); + unsigned long enableNonblocking = 0; + ioctlsocket( i->second->impl_->Socket(), FIONBIO, &enableNonblocking ); // make the socket blocking again + } + } + + void Break() + { + break_ = true; + } + + void AsynchronousBreak() + { + break_ = true; + SetEvent( breakEvent_ ); + } +}; + + + +SocketReceiveMultiplexer::SocketReceiveMultiplexer() +{ + impl_ = new Implementation(); +} + +SocketReceiveMultiplexer::~SocketReceiveMultiplexer() +{ + delete impl_; +} + +void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener ) +{ + impl_->AttachSocketListener( socket, listener ); +} + +void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener ) +{ + impl_->DetachSocketListener( socket, listener ); +} + +void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener ) +{ + impl_->AttachPeriodicTimerListener( periodMilliseconds, listener ); +} + +void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener ) +{ + impl_->AttachPeriodicTimerListener( initialDelayMilliseconds, periodMilliseconds, listener ); +} + +void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener ) +{ + impl_->DetachPeriodicTimerListener( listener ); +} + +void SocketReceiveMultiplexer::Run() +{ + impl_->Run(); +} + +void SocketReceiveMultiplexer::RunUntilSigInt() +{ + assert( multiplexerInstanceToAbortWithSigInt_ == 0 ); /* at present we support only one multiplexer instance running until sig int */ + multiplexerInstanceToAbortWithSigInt_ = this; +#ifndef WINCE + signal( SIGINT, InterruptSignalHandler ); +#endif + impl_->Run(); +#ifndef WINCE + signal( SIGINT, SIG_DFL ); +#endif + multiplexerInstanceToAbortWithSigInt_ = 0; +} + +void SocketReceiveMultiplexer::Break() +{ + impl_->Break(); +} + +void SocketReceiveMultiplexer::AsynchronousBreak() +{ + impl_->AsynchronousBreak(); +} + diff --git a/src/osc/oscPack/osc/MessageMappingOscPacketListener.h b/src/osc/oscPack/osc/MessageMappingOscPacketListener.h new file mode 100644 index 0000000..fc7f75a --- /dev/null +++ b/src/osc/oscPack/osc/MessageMappingOscPacketListener.h @@ -0,0 +1,80 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_MESSAGEMAPPINGOSCPACKETLISTENER_H +#define INCLUDED_OSCPACK_MESSAGEMAPPINGOSCPACKETLISTENER_H + +#include <cstring> +#include <map> + +#include "OscPacketListener.h" + + + +namespace osc{ + +template< class T > +class MessageMappingOscPacketListener : public OscPacketListener{ +public: + typedef void (T::*function_type)(const osc::ReceivedMessage&, const IpEndpointName&); + +protected: + void RegisterMessageFunction( const char *addressPattern, function_type f ) + { + functions_.insert( std::make_pair( addressPattern, f ) ); + } + + virtual void ProcessMessage( const osc::ReceivedMessage& m, + const IpEndpointName& remoteEndpoint ) + { + typename function_map_type::iterator i = functions_.find( m.AddressPattern() ); + if( i != functions_.end() ) + (dynamic_cast<T*>(this)->*(i->second))( m, remoteEndpoint ); + } + +private: + struct cstr_compare{ + bool operator()( const char *lhs, const char *rhs ) const + { return std::strcmp( lhs, rhs ) < 0; } + }; + + typedef std::map<const char*, function_type, cstr_compare> function_map_type; + function_map_type functions_; +}; + +} // namespace osc + +#endif /* INCLUDED_OSCPACK_MESSAGEMAPPINGOSCPACKETLISTENER_H */ \ No newline at end of file diff --git a/src/osc/oscPack/osc/OscException.h b/src/osc/oscPack/osc/OscException.h new file mode 100644 index 0000000..5742762 --- /dev/null +++ b/src/osc/oscPack/osc/OscException.h @@ -0,0 +1,62 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_OSCEXCEPTION_H +#define INCLUDED_OSCPACK_OSCEXCEPTION_H + +#include <exception> + +namespace osc{ + +class Exception : public std::exception { + const char *what_; + +public: + Exception() throw() {} + Exception( const Exception& src ) throw() + : std::exception( src ) + , what_( src.what_ ) {} + Exception( const char *w ) throw() + : what_( w ) {} + Exception& operator=( const Exception& src ) throw() + { what_ = src.what_; return *this; } + virtual ~Exception() throw() {} + virtual const char* what() const throw() { return what_; } +}; + +} // namespace osc + +#endif /* INCLUDED_OSCPACK_OSCEXCEPTION_H */ diff --git a/src/osc/oscPack/osc/OscHostEndianness.h b/src/osc/oscPack/osc/OscHostEndianness.h new file mode 100644 index 0000000..3bcc376 --- /dev/null +++ b/src/osc/oscPack/osc/OscHostEndianness.h @@ -0,0 +1,127 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_OSCHOSTENDIANNESS_H +#define INCLUDED_OSCPACK_OSCHOSTENDIANNESS_H + +/* + Make sure either OSC_HOST_LITTLE_ENDIAN or OSC_HOST_BIG_ENDIAN is defined + + We try to use preprocessor symbols to deduce the host endianness. + + Alternatively you can define one of the above symbols from the command line. + Usually you do this with the -D flag to the compiler. e.g.: + + $ g++ -DOSC_HOST_LITTLE_ENDIAN ... +*/ + +#if defined(OSC_HOST_LITTLE_ENDIAN) || defined(OSC_HOST_BIG_ENDIAN) + +// endianness defined on the command line. nothing to do here. + +#elif defined(__WIN32__) || defined(WIN32) || defined(WINCE) + +// assume that __WIN32__ is only defined on little endian systems + +#define OSC_HOST_LITTLE_ENDIAN 1 +#undef OSC_HOST_BIG_ENDIAN + +#elif defined(__APPLE__) + +#if defined(__LITTLE_ENDIAN__) + +#define OSC_HOST_LITTLE_ENDIAN 1 +#undef OSC_HOST_BIG_ENDIAN + +#elif defined(__BIG_ENDIAN__) + +#define OSC_HOST_BIG_ENDIAN 1 +#undef OSC_HOST_LITTLE_ENDIAN + +#endif + +#elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) + +// should cover gcc and clang + +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + +#define OSC_HOST_LITTLE_ENDIAN 1 +#undef OSC_HOST_BIG_ENDIAN + +#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + +#define OSC_HOST_BIG_ENDIAN 1 +#undef OSC_HOST_LITTLE_ENDIAN + +#endif + +#else + +// gcc defines __LITTLE_ENDIAN__ and __BIG_ENDIAN__ +// for others used here see http://sourceforge.net/p/predef/wiki/Endianness/ +#if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) \ + || (defined(__ARMEL__) && !defined(__ARMEB__)) \ + || (defined(__AARCH64EL__) && !defined(__AARCH64EB__)) \ + || (defined(_MIPSEL) && !defined(_MIPSEB)) \ + || (defined(__MIPSEL) && !defined(__MIPSEB)) \ + || (defined(__MIPSEL__) && !defined(__MIPSEB__)) + +#define OSC_HOST_LITTLE_ENDIAN 1 +#undef OSC_HOST_BIG_ENDIAN + +#elif (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) \ + || (defined(__ARMEB__) && !defined(__ARMEL__)) \ + || (defined(__AARCH64EB__) && !defined(__AARCH64EL__)) \ + || (defined(_MIPSEB) && !defined(_MIPSEL)) \ + || (defined(__MIPSEB) && !defined(__MIPSEL)) \ + || (defined(__MIPSEB__) && !defined(__MIPSEL__)) + +#define OSC_HOST_BIG_ENDIAN 1 +#undef OSC_HOST_LITTLE_ENDIAN + +#endif + +#endif + +#if !defined(OSC_HOST_LITTLE_ENDIAN) && !defined(OSC_HOST_BIG_ENDIAN) + +#error please edit OSCHostEndianness.h or define one of {OSC_HOST_LITTLE_ENDIAN, OSC_HOST_BIG_ENDIAN} to configure endianness + +#endif + +#endif /* INCLUDED_OSCPACK_OSCHOSTENDIANNESS_H */ + diff --git a/src/osc/oscPack/osc/OscOutboundPacketStream.cpp b/src/osc/oscPack/osc/OscOutboundPacketStream.cpp new file mode 100644 index 0000000..e54cbd3 --- /dev/null +++ b/src/osc/oscPack/osc/OscOutboundPacketStream.cpp @@ -0,0 +1,683 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#include "OscOutboundPacketStream.h" + +#if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) +#include <malloc.h> // for alloca +#else +//#include <alloca.h> // alloca on Linux (also OSX) +#include <stdlib.h> // alloca on OSX and FreeBSD (and Linux?) +#endif + +#include <cassert> +#include <cstring> // memcpy, memmove, strcpy, strlen +#include <cstddef> // ptrdiff_t + +#include "OscHostEndianness.h" + +#if defined(__BORLANDC__) // workaround for BCB4 release build intrinsics bug +namespace std { +using ::__strcpy__; // avoid error: E2316 '__strcpy__' is not a member of 'std'. +} +#endif + +namespace osc{ + +static void FromInt32( char *p, int32 x ) +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::int32 i; + char c[4]; + } u; + + u.i = x; + + p[3] = u.c[0]; + p[2] = u.c[1]; + p[1] = u.c[2]; + p[0] = u.c[3]; +#else + *reinterpret_cast<int32*>(p) = x; +#endif +} + + +static void FromUInt32( char *p, uint32 x ) +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::uint32 i; + char c[4]; + } u; + + u.i = x; + + p[3] = u.c[0]; + p[2] = u.c[1]; + p[1] = u.c[2]; + p[0] = u.c[3]; +#else + *reinterpret_cast<uint32*>(p) = x; +#endif +} + + +static void FromInt64( char *p, int64 x ) +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::int64 i; + char c[8]; + } u; + + u.i = x; + + p[7] = u.c[0]; + p[6] = u.c[1]; + p[5] = u.c[2]; + p[4] = u.c[3]; + p[3] = u.c[4]; + p[2] = u.c[5]; + p[1] = u.c[6]; + p[0] = u.c[7]; +#else + *reinterpret_cast<int64*>(p) = x; +#endif +} + + +static void FromUInt64( char *p, uint64 x ) +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::uint64 i; + char c[8]; + } u; + + u.i = x; + + p[7] = u.c[0]; + p[6] = u.c[1]; + p[5] = u.c[2]; + p[4] = u.c[3]; + p[3] = u.c[4]; + p[2] = u.c[5]; + p[1] = u.c[6]; + p[0] = u.c[7]; +#else + *reinterpret_cast<uint64*>(p) = x; +#endif +} + + +// round up to the next highest multiple of 4. unless x is already a multiple of 4 +static inline std::size_t RoundUp4( std::size_t x ) +{ + return (x + 3) & ~((std::size_t)0x03); +} + + +OutboundPacketStream::OutboundPacketStream( char *buffer, std::size_t capacity ) + : data_( buffer ) + , end_( data_ + capacity ) + , typeTagsCurrent_( end_ ) + , messageCursor_( data_ ) + , argumentCurrent_( data_ ) + , elementSizePtr_( 0 ) + , messageIsInProgress_( false ) +{ + // sanity check integer types declared in OscTypes.h + // you'll need to fix OscTypes.h if any of these asserts fail + assert( sizeof(osc::int32) == 4 ); + assert( sizeof(osc::uint32) == 4 ); + assert( sizeof(osc::int64) == 8 ); + assert( sizeof(osc::uint64) == 8 ); +} + + +OutboundPacketStream::~OutboundPacketStream() +{ + +} + + +char *OutboundPacketStream::BeginElement( char *beginPtr ) +{ + if( elementSizePtr_ == 0 ){ + + elementSizePtr_ = reinterpret_cast<uint32*>(data_); + + return beginPtr; + + }else{ + // store an offset to the old element size ptr in the element size slot + // we store an offset rather than the actual pointer to be 64 bit clean. + *reinterpret_cast<uint32*>(beginPtr) = + (uint32)(reinterpret_cast<char*>(elementSizePtr_) - data_); + + elementSizePtr_ = reinterpret_cast<uint32*>(beginPtr); + + return beginPtr + 4; + } +} + + +void OutboundPacketStream::EndElement( char *endPtr ) +{ + assert( elementSizePtr_ != 0 ); + + if( elementSizePtr_ == reinterpret_cast<uint32*>(data_) ){ + + elementSizePtr_ = 0; + + }else{ + // while building an element, an offset to the containing element's + // size slot is stored in the elements size slot (or a ptr to data_ + // if there is no containing element). We retrieve that here + uint32 *previousElementSizePtr = + reinterpret_cast<uint32*>(data_ + *elementSizePtr_); + + // then we store the element size in the slot. note that the element + // size does not include the size slot, hence the - 4 below. + + std::ptrdiff_t d = endPtr - reinterpret_cast<char*>(elementSizePtr_); + // assert( d >= 4 && d <= 0x7FFFFFFF ); // assume packets smaller than 2Gb + + uint32 elementSize = static_cast<uint32>(d - 4); + FromUInt32( reinterpret_cast<char*>(elementSizePtr_), elementSize ); + + // finally, we reset the element size ptr to the containing element + elementSizePtr_ = previousElementSizePtr; + } +} + + +bool OutboundPacketStream::ElementSizeSlotRequired() const +{ + return (elementSizePtr_ != 0); +} + + +void OutboundPacketStream::CheckForAvailableBundleSpace() +{ + std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0) + 16; + + if( required > Capacity() ) + throw OutOfBufferMemoryException(); +} + + +void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern ) +{ + // plus 4 for at least four bytes of type tag + std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0) + + RoundUp4(std::strlen(addressPattern) + 1) + 4; + + if( required > Capacity() ) + throw OutOfBufferMemoryException(); +} + + +void OutboundPacketStream::CheckForAvailableArgumentSpace( std::size_t argumentLength ) +{ + // plus three for extra type tag, comma and null terminator + std::size_t required = (argumentCurrent_ - data_) + argumentLength + + RoundUp4( (end_ - typeTagsCurrent_) + 3 ); + + if( required > Capacity() ) + throw OutOfBufferMemoryException(); +} + + +void OutboundPacketStream::Clear() +{ + typeTagsCurrent_ = end_; + messageCursor_ = data_; + argumentCurrent_ = data_; + elementSizePtr_ = 0; + messageIsInProgress_ = false; +} + + +std::size_t OutboundPacketStream::Capacity() const +{ + return end_ - data_; +} + + +std::size_t OutboundPacketStream::Size() const +{ + std::size_t result = argumentCurrent_ - data_; + if( IsMessageInProgress() ){ + // account for the length of the type tag string. the total type tag + // includes an initial comma, plus at least one terminating \0 + result += RoundUp4( (end_ - typeTagsCurrent_) + 2 ); + } + + return result; +} + + +const char *OutboundPacketStream::Data() const +{ + return data_; +} + + +bool OutboundPacketStream::IsReady() const +{ + return (!IsMessageInProgress() && !IsBundleInProgress()); +} + + +bool OutboundPacketStream::IsMessageInProgress() const +{ + return messageIsInProgress_; +} + + +bool OutboundPacketStream::IsBundleInProgress() const +{ + return (elementSizePtr_ != 0); +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& rhs ) +{ + if( IsMessageInProgress() ) + throw MessageInProgressException(); + + CheckForAvailableBundleSpace(); + + messageCursor_ = BeginElement( messageCursor_ ); + + std::memcpy( messageCursor_, "#bundle\0", 8 ); + FromUInt64( messageCursor_ + 8, rhs.timeTag ); + + messageCursor_ += 16; + argumentCurrent_ = messageCursor_; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const BundleTerminator& rhs ) +{ + (void) rhs; + + if( !IsBundleInProgress() ) + throw BundleNotInProgressException(); + if( IsMessageInProgress() ) + throw MessageInProgressException(); + + EndElement( messageCursor_ ); + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs ) +{ + if( IsMessageInProgress() ) + throw MessageInProgressException(); + + CheckForAvailableMessageSpace( rhs.addressPattern ); + + messageCursor_ = BeginElement( messageCursor_ ); + + std::strcpy( messageCursor_, rhs.addressPattern ); + std::size_t rhsLength = std::strlen(rhs.addressPattern); + messageCursor_ += rhsLength + 1; + + // zero pad to 4-byte boundary + std::size_t i = rhsLength + 1; + while( i & 0x3 ){ + *messageCursor_++ = '\0'; + ++i; + } + + argumentCurrent_ = messageCursor_; + typeTagsCurrent_ = end_; + + messageIsInProgress_ = true; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator& rhs ) +{ + (void) rhs; + + if( !IsMessageInProgress() ) + throw MessageNotInProgressException(); + + std::size_t typeTagsCount = end_ - typeTagsCurrent_; + + if( typeTagsCount ){ + + char *tempTypeTags = (char*)alloca(typeTagsCount); + std::memcpy( tempTypeTags, typeTagsCurrent_, typeTagsCount ); + + // slot size includes comma and null terminator + std::size_t typeTagSlotSize = RoundUp4( typeTagsCount + 2 ); + + std::size_t argumentsSize = argumentCurrent_ - messageCursor_; + + std::memmove( messageCursor_ + typeTagSlotSize, messageCursor_, argumentsSize ); + + messageCursor_[0] = ','; + // copy type tags in reverse (really forward) order + for( std::size_t i=0; i < typeTagsCount; ++i ) + messageCursor_[i+1] = tempTypeTags[ (typeTagsCount-1) - i ]; + + char *p = messageCursor_ + 1 + typeTagsCount; + for( std::size_t i=0; i < (typeTagSlotSize - (typeTagsCount + 1)); ++i ) + *p++ = '\0'; + + typeTagsCurrent_ = end_; + + // advance messageCursor_ for next message + messageCursor_ += typeTagSlotSize + argumentsSize; + + }else{ + // send an empty type tags string + std::memcpy( messageCursor_, ",\0\0\0", 4 ); + + // advance messageCursor_ for next message + messageCursor_ += 4; + } + + argumentCurrent_ = messageCursor_; + + EndElement( messageCursor_ ); + + messageIsInProgress_ = false; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs ) +{ + CheckForAvailableArgumentSpace(0); + + *(--typeTagsCurrent_) = (char)((rhs) ? TRUE_TYPE_TAG : FALSE_TYPE_TAG); + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs ) +{ + (void) rhs; + CheckForAvailableArgumentSpace(0); + + *(--typeTagsCurrent_) = NIL_TYPE_TAG; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs ) +{ + (void) rhs; + CheckForAvailableArgumentSpace(0); + + *(--typeTagsCurrent_) = INFINITUM_TYPE_TAG; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs ) +{ + CheckForAvailableArgumentSpace(4); + + *(--typeTagsCurrent_) = INT32_TYPE_TAG; + FromInt32( argumentCurrent_, rhs ); + argumentCurrent_ += 4; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( float rhs ) +{ + CheckForAvailableArgumentSpace(4); + + *(--typeTagsCurrent_) = FLOAT_TYPE_TAG; + +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + float f; + char c[4]; + } u; + + u.f = rhs; + + argumentCurrent_[3] = u.c[0]; + argumentCurrent_[2] = u.c[1]; + argumentCurrent_[1] = u.c[2]; + argumentCurrent_[0] = u.c[3]; +#else + *reinterpret_cast<float*>(argumentCurrent_) = rhs; +#endif + + argumentCurrent_ += 4; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( char rhs ) +{ + CheckForAvailableArgumentSpace(4); + + *(--typeTagsCurrent_) = CHAR_TYPE_TAG; + FromInt32( argumentCurrent_, rhs ); + argumentCurrent_ += 4; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs ) +{ + CheckForAvailableArgumentSpace(4); + + *(--typeTagsCurrent_) = RGBA_COLOR_TYPE_TAG; + FromUInt32( argumentCurrent_, rhs ); + argumentCurrent_ += 4; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs ) +{ + CheckForAvailableArgumentSpace(4); + + *(--typeTagsCurrent_) = MIDI_MESSAGE_TYPE_TAG; + FromUInt32( argumentCurrent_, rhs ); + argumentCurrent_ += 4; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs ) +{ + CheckForAvailableArgumentSpace(8); + + *(--typeTagsCurrent_) = INT64_TYPE_TAG; + FromInt64( argumentCurrent_, rhs ); + argumentCurrent_ += 8; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs ) +{ + CheckForAvailableArgumentSpace(8); + + *(--typeTagsCurrent_) = TIME_TAG_TYPE_TAG; + FromUInt64( argumentCurrent_, rhs ); + argumentCurrent_ += 8; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( double rhs ) +{ + CheckForAvailableArgumentSpace(8); + + *(--typeTagsCurrent_) = DOUBLE_TYPE_TAG; + +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + double f; + char c[8]; + } u; + + u.f = rhs; + + argumentCurrent_[7] = u.c[0]; + argumentCurrent_[6] = u.c[1]; + argumentCurrent_[5] = u.c[2]; + argumentCurrent_[4] = u.c[3]; + argumentCurrent_[3] = u.c[4]; + argumentCurrent_[2] = u.c[5]; + argumentCurrent_[1] = u.c[6]; + argumentCurrent_[0] = u.c[7]; +#else + *reinterpret_cast<double*>(argumentCurrent_) = rhs; +#endif + + argumentCurrent_ += 8; + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs ) +{ + CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) ); + + *(--typeTagsCurrent_) = STRING_TYPE_TAG; + std::strcpy( argumentCurrent_, rhs ); + std::size_t rhsLength = std::strlen(rhs); + argumentCurrent_ += rhsLength + 1; + + // zero pad to 4-byte boundary + std::size_t i = rhsLength + 1; + while( i & 0x3 ){ + *argumentCurrent_++ = '\0'; + ++i; + } + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs ) +{ + CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) ); + + *(--typeTagsCurrent_) = SYMBOL_TYPE_TAG; + std::strcpy( argumentCurrent_, rhs ); + std::size_t rhsLength = std::strlen(rhs); + argumentCurrent_ += rhsLength + 1; + + // zero pad to 4-byte boundary + std::size_t i = rhsLength + 1; + while( i & 0x3 ){ + *argumentCurrent_++ = '\0'; + ++i; + } + + return *this; +} + + +OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs ) +{ + CheckForAvailableArgumentSpace( 4 + RoundUp4(rhs.size) ); + + *(--typeTagsCurrent_) = BLOB_TYPE_TAG; + FromUInt32( argumentCurrent_, rhs.size ); + argumentCurrent_ += 4; + + std::memcpy( argumentCurrent_, rhs.data, rhs.size ); + argumentCurrent_ += rhs.size; + + // zero pad to 4-byte boundary + unsigned long i = rhs.size; + while( i & 0x3 ){ + *argumentCurrent_++ = '\0'; + ++i; + } + + return *this; +} + +OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayInitiator& rhs ) +{ + (void) rhs; + CheckForAvailableArgumentSpace(0); + + *(--typeTagsCurrent_) = ARRAY_BEGIN_TYPE_TAG; + + return *this; +} + +OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayTerminator& rhs ) +{ + (void) rhs; + CheckForAvailableArgumentSpace(0); + + *(--typeTagsCurrent_) = ARRAY_END_TYPE_TAG; + + return *this; +} + +} // namespace osc + + diff --git a/src/osc/oscPack/osc/OscOutboundPacketStream.h b/src/osc/oscPack/osc/OscOutboundPacketStream.h new file mode 100644 index 0000000..26f3e58 --- /dev/null +++ b/src/osc/oscPack/osc/OscOutboundPacketStream.h @@ -0,0 +1,154 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_OSCOUTBOUNDPACKETSTREAM_H +#define INCLUDED_OSCPACK_OSCOUTBOUNDPACKETSTREAM_H + +#include <cstring> // size_t + +#include "OscTypes.h" +#include "OscException.h" + + +namespace osc{ + +class OutOfBufferMemoryException : public Exception{ +public: + OutOfBufferMemoryException( const char *w="out of buffer memory" ) + : Exception( w ) {} +}; + +class BundleNotInProgressException : public Exception{ +public: + BundleNotInProgressException( + const char *w="call to EndBundle when bundle is not in progress" ) + : Exception( w ) {} +}; + +class MessageInProgressException : public Exception{ +public: + MessageInProgressException( + const char *w="opening or closing bundle or message while message is in progress" ) + : Exception( w ) {} +}; + +class MessageNotInProgressException : public Exception{ +public: + MessageNotInProgressException( + const char *w="call to EndMessage when message is not in progress" ) + : Exception( w ) {} +}; + + +class OutboundPacketStream{ +public: + OutboundPacketStream( char *buffer, std::size_t capacity ); + ~OutboundPacketStream(); + + void Clear(); + + std::size_t Capacity() const; + + // invariant: size() is valid even while building a message. + std::size_t Size() const; + + const char *Data() const; + + // indicates that all messages have been closed with a matching EndMessage + // and all bundles have been closed with a matching EndBundle + bool IsReady() const; + + bool IsMessageInProgress() const; + bool IsBundleInProgress() const; + + OutboundPacketStream& operator<<( const BundleInitiator& rhs ); + OutboundPacketStream& operator<<( const BundleTerminator& rhs ); + + OutboundPacketStream& operator<<( const BeginMessage& rhs ); + OutboundPacketStream& operator<<( const MessageTerminator& rhs ); + + OutboundPacketStream& operator<<( bool rhs ); + OutboundPacketStream& operator<<( const NilType& rhs ); + OutboundPacketStream& operator<<( const InfinitumType& rhs ); + OutboundPacketStream& operator<<( int32 rhs ); + +#if !(defined(__x86_64__) || defined(_M_X64)) + OutboundPacketStream& operator<<( int rhs ) + { *this << (int32)rhs; return *this; } +#endif + + OutboundPacketStream& operator<<( float rhs ); + OutboundPacketStream& operator<<( char rhs ); + OutboundPacketStream& operator<<( const RgbaColor& rhs ); + OutboundPacketStream& operator<<( const MidiMessage& rhs ); + OutboundPacketStream& operator<<( int64 rhs ); + OutboundPacketStream& operator<<( const TimeTag& rhs ); + OutboundPacketStream& operator<<( double rhs ); + OutboundPacketStream& operator<<( const char* rhs ); + OutboundPacketStream& operator<<( const Symbol& rhs ); + OutboundPacketStream& operator<<( const Blob& rhs ); + + OutboundPacketStream& operator<<( const ArrayInitiator& rhs ); + OutboundPacketStream& operator<<( const ArrayTerminator& rhs ); + +private: + + char *BeginElement( char *beginPtr ); + void EndElement( char *endPtr ); + + bool ElementSizeSlotRequired() const; + void CheckForAvailableBundleSpace(); + void CheckForAvailableMessageSpace( const char *addressPattern ); + void CheckForAvailableArgumentSpace( std::size_t argumentLength ); + + char *data_; + char *end_; + + char *typeTagsCurrent_; // stored in reverse order + char *messageCursor_; + char *argumentCurrent_; + + // elementSizePtr_ has two special values: 0 indicates that a bundle + // isn't open, and elementSizePtr_==data_ indicates that a bundle is + // open but that it doesn't have a size slot (ie the outermost bundle) + uint32 *elementSizePtr_; + + bool messageIsInProgress_; +}; + +} // namespace osc + +#endif /* INCLUDED_OSCPACK_OSCOUTBOUNDPACKETSTREAM_H */ diff --git a/src/osc/oscPack/osc/OscPacketListener.h b/src/osc/oscPack/osc/OscPacketListener.h new file mode 100644 index 0000000..c77e924 --- /dev/null +++ b/src/osc/oscPack/osc/OscPacketListener.h @@ -0,0 +1,79 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_OSCPACKETLISTENER_H +#define INCLUDED_OSCPACK_OSCPACKETLISTENER_H + +#include "OscReceivedElements.h" +#include "../ip/PacketListener.h" + + +namespace osc{ + +class OscPacketListener : public PacketListener{ +protected: + virtual void ProcessBundle( const osc::ReceivedBundle& b, + const IpEndpointName& remoteEndpoint ) + { + // ignore bundle time tag for now + + for( ReceivedBundle::const_iterator i = b.ElementsBegin(); + i != b.ElementsEnd(); ++i ){ + if( i->IsBundle() ) + ProcessBundle( ReceivedBundle(*i), remoteEndpoint ); + else + ProcessMessage( ReceivedMessage(*i), remoteEndpoint ); + } + } + + virtual void ProcessMessage( const osc::ReceivedMessage& m, + const IpEndpointName& remoteEndpoint ) = 0; + +public: + virtual void ProcessPacket( const char *data, int size, + const IpEndpointName& remoteEndpoint ) + { + osc::ReceivedPacket p( data, size ); + if( p.IsBundle() ) + ProcessBundle( ReceivedBundle(p), remoteEndpoint ); + else + ProcessMessage( ReceivedMessage(p), remoteEndpoint ); + } +}; + +} // namespace osc + +#endif /* INCLUDED_OSCPACK_OSCPACKETLISTENER_H */ diff --git a/src/osc/oscPack/osc/OscPrintReceivedElements.cpp b/src/osc/oscPack/osc/OscPrintReceivedElements.cpp new file mode 100644 index 0000000..72e0bc5 --- /dev/null +++ b/src/osc/oscPack/osc/OscPrintReceivedElements.cpp @@ -0,0 +1,261 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#include "OscPrintReceivedElements.h" + +#include <cstring> +#include <ctime> +#include <iostream> +#include <iomanip> + +#if defined(__BORLANDC__) // workaround for BCB4 release build intrinsics bug +namespace std { +using ::__strcpy__; // avoid error: E2316 '__strcpy__' is not a member of 'std'. +} +#endif + +namespace osc{ + + +std::ostream& operator<<( std::ostream & os, + const ReceivedMessageArgument& arg ) +{ + switch( arg.TypeTag() ){ + case TRUE_TYPE_TAG: + os << "bool:true"; + break; + + case FALSE_TYPE_TAG: + os << "bool:false"; + break; + + case NIL_TYPE_TAG: + os << "(Nil)"; + break; + + case INFINITUM_TYPE_TAG: + os << "(Infinitum)"; + break; + + case INT32_TYPE_TAG: + os << "int32:" << arg.AsInt32Unchecked(); + break; + + case FLOAT_TYPE_TAG: + os << "float32:" << arg.AsFloatUnchecked(); + break; + + case CHAR_TYPE_TAG: + { + char s[2] = {0}; + s[0] = arg.AsCharUnchecked(); + os << "char:'" << s << "'"; + } + break; + + case RGBA_COLOR_TYPE_TAG: + { + uint32 color = arg.AsRgbaColorUnchecked(); + + os << "RGBA:0x" + << std::hex << std::setfill('0') + << std::setw(2) << (int)((color>>24) & 0xFF) + << std::setw(2) << (int)((color>>16) & 0xFF) + << std::setw(2) << (int)((color>>8) & 0xFF) + << std::setw(2) << (int)(color & 0xFF) + << std::setfill(' '); + os.unsetf(std::ios::basefield); + } + break; + + case MIDI_MESSAGE_TYPE_TAG: + { + uint32 m = arg.AsMidiMessageUnchecked(); + os << "midi (port, status, data1, data2):<<" + << std::hex << std::setfill('0') + << "0x" << std::setw(2) << (int)((m>>24) & 0xFF) + << " 0x" << std::setw(2) << (int)((m>>16) & 0xFF) + << " 0x" << std::setw(2) << (int)((m>>8) & 0xFF) + << " 0x" << std::setw(2) << (int)(m & 0xFF) + << std::setfill(' ') << ">>"; + os.unsetf(std::ios::basefield); + } + break; + + case INT64_TYPE_TAG: + os << "int64:" << arg.AsInt64Unchecked(); + break; + + case TIME_TAG_TYPE_TAG: + { + os << "OSC-timetag:" << arg.AsTimeTagUnchecked() << " "; + + std::time_t t = + (unsigned long)( arg.AsTimeTagUnchecked() >> 32 ); + + const char *timeString = std::ctime( &t ); + size_t len = std::strlen( timeString ); + + // -1 to omit trailing newline from string returned by ctime() + if( len > 1 ) + os.write( timeString, len - 1 ); + } + break; + + case DOUBLE_TYPE_TAG: + os << "double:" << arg.AsDoubleUnchecked(); + break; + + case STRING_TYPE_TAG: + os << "OSC-string:`" << arg.AsStringUnchecked() << "'"; + break; + + case SYMBOL_TYPE_TAG: + os << "OSC-string (symbol):`" << arg.AsSymbolUnchecked() << "'"; + break; + + case BLOB_TYPE_TAG: + { + const void *data; + osc_bundle_element_size_t size; + arg.AsBlobUnchecked( data, size ); + os << "OSC-blob:<<" << std::hex << std::setfill('0'); + unsigned char *p = (unsigned char*)data; + for( osc_bundle_element_size_t i = 0; i < size; ++i ){ + os << "0x" << std::setw(2) << int(p[i]); + if( i != size-1 ) + os << ' '; + } + os.unsetf(std::ios::basefield); + os << ">>" << std::setfill(' '); + } + break; + + case ARRAY_BEGIN_TYPE_TAG: + os << "["; + break; + + case ARRAY_END_TYPE_TAG: + os << "]"; + break; + + default: + os << "unknown"; + } + + return os; +} + + +std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m ) +{ + os << "["; + if( m.AddressPatternIsUInt32() ) + os << m.AddressPatternAsUInt32(); + else + os << m.AddressPattern(); + + bool first = true; + for( ReceivedMessage::const_iterator i = m.ArgumentsBegin(); + i != m.ArgumentsEnd(); ++i ){ + if( first ){ + os << " "; + first = false; + }else{ + os << ", "; + } + + os << *i; + } + + os << "]"; + + return os; +} + + +std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b ) +{ + static int indent = 0; + + for( int j=0; j < indent; ++j ) + os << " "; + os << "{ ( "; + if( b.TimeTag() == 1 ) + os << "immediate"; + else + os << b.TimeTag(); + os << " )\n"; + + ++indent; + + for( ReceivedBundle::const_iterator i = b.ElementsBegin(); + i != b.ElementsEnd(); ++i ){ + if( i->IsBundle() ){ + ReceivedBundle b(*i); + os << b << "\n"; + }else{ + ReceivedMessage m(*i); + for( int j=0; j < indent; ++j ) + os << " "; + os << m << "\n"; + } + } + + --indent; + + for( int j=0; j < indent; ++j ) + os << " "; + os << "}"; + + return os; +} + + +std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p ) +{ + if( p.IsBundle() ){ + ReceivedBundle b(p); + os << b << "\n"; + }else{ + ReceivedMessage m(p); + os << m << "\n"; + } + + return os; +} + +} // namespace osc diff --git a/src/osc/oscPack/osc/OscPrintReceivedElements.h b/src/osc/oscPack/osc/OscPrintReceivedElements.h new file mode 100644 index 0000000..7561c01 --- /dev/null +++ b/src/osc/oscPack/osc/OscPrintReceivedElements.h @@ -0,0 +1,54 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_OSCPRINTRECEIVEDELEMENTS_H +#define INCLUDED_OSCPACK_OSCPRINTRECEIVEDELEMENTS_H + +#include <iosfwd> + +#include "OscReceivedElements.h" + + +namespace osc{ + +std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p ); +std::ostream& operator<<( std::ostream & os, const ReceivedMessageArgument& arg ); +std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m ); +std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b ); + +} // namespace osc + +#endif /* INCLUDED_OSCPACK_OSCPRINTRECEIVEDELEMENTS_H */ diff --git a/src/osc/oscPack/osc/OscReceivedElements.cpp b/src/osc/oscPack/osc/OscReceivedElements.cpp new file mode 100644 index 0000000..dd19a44 --- /dev/null +++ b/src/osc/oscPack/osc/OscReceivedElements.cpp @@ -0,0 +1,801 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#include "OscReceivedElements.h" + +#include "OscHostEndianness.h" + +#include <cstddef> // ptrdiff_t + +namespace osc{ + + +// return the first 4 byte boundary after the end of a str4 +// be careful about calling this version if you don't know whether +// the string is terminated correctly. +static inline const char* FindStr4End( const char *p ) +{ + if( p[0] == '\0' ) // special case for SuperCollider integer address pattern + return p + 4; + + p += 3; + + while( *p ) + p += 4; + + return p + 1; +} + + +// return the first 4 byte boundary after the end of a str4 +// returns 0 if p == end or if the string is unterminated +static inline const char* FindStr4End( const char *p, const char *end ) +{ + if(p >= end) { + return 0; + } + + if( p[0] == '\0' ) { // special case for SuperCollider integer address pattern + return p + 4; + } + + p += 3; + end -= 1; + + while( p < end && *p ) { + p += 4; + } + + if( *p ) { + return 0; + } + else { + return p + 1; + } +} + + +// round up to the next highest multiple of 4. unless x is already a multiple of 4 +static inline uint32 RoundUp4( uint32 x ) +{ + return (x + 3) & ~((uint32)0x03); +} + + +static inline int32 ToInt32( const char *p ) +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::int32 i; + char c[4]; + } u; + + u.c[0] = p[3]; + u.c[1] = p[2]; + u.c[2] = p[1]; + u.c[3] = p[0]; + + return u.i; +#else + return *(int32*)p; +#endif +} + + +static inline uint32 ToUInt32( const char *p ) +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::uint32 i; + char c[4]; + } u; + + u.c[0] = p[3]; + u.c[1] = p[2]; + u.c[2] = p[1]; + u.c[3] = p[0]; + + return u.i; +#else + return *(uint32*)p; +#endif +} + + +static inline int64 ToInt64( const char *p ) +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::int64 i; + char c[8]; + } u; + + u.c[0] = p[7]; + u.c[1] = p[6]; + u.c[2] = p[5]; + u.c[3] = p[4]; + u.c[4] = p[3]; + u.c[5] = p[2]; + u.c[6] = p[1]; + u.c[7] = p[0]; + + return u.i; +#else + return *(int64*)p; +#endif +} + + +static inline uint64 ToUInt64( const char *p ) +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::uint64 i; + char c[8]; + } u; + + u.c[0] = p[7]; + u.c[1] = p[6]; + u.c[2] = p[5]; + u.c[3] = p[4]; + u.c[4] = p[3]; + u.c[5] = p[2]; + u.c[6] = p[1]; + u.c[7] = p[0]; + + return u.i; +#else + return *(uint64*)p; +#endif +} + +//------------------------------------------------------------------------------ + +bool ReceivedPacket::IsBundle() const +{ + return (Size() > 0 && Contents()[0] == '#'); +} + +//------------------------------------------------------------------------------ + +bool ReceivedBundleElement::IsBundle() const +{ + return (Size() > 0 && Contents()[0] == '#'); +} + + +osc_bundle_element_size_t ReceivedBundleElement::Size() const +{ + return ToInt32( sizePtr_ ); +} + +//------------------------------------------------------------------------------ + +bool ReceivedMessageArgument::AsBool() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == TRUE_TYPE_TAG ) + return true; + else if( *typeTagPtr_ == FALSE_TYPE_TAG ) + return false; + else + throw WrongArgumentTypeException(); +} + + +bool ReceivedMessageArgument::AsBoolUnchecked() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == TRUE_TYPE_TAG ) + return true; + else + return false; +} + + +int32 ReceivedMessageArgument::AsInt32() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == INT32_TYPE_TAG ) + return AsInt32Unchecked(); + else + throw WrongArgumentTypeException(); +} + + +int32 ReceivedMessageArgument::AsInt32Unchecked() const +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + osc::int32 i; + char c[4]; + } u; + + u.c[0] = argumentPtr_[3]; + u.c[1] = argumentPtr_[2]; + u.c[2] = argumentPtr_[1]; + u.c[3] = argumentPtr_[0]; + + return u.i; +#else + return *(int32*)argument_; +#endif +} + + +float ReceivedMessageArgument::AsFloat() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == FLOAT_TYPE_TAG ) + return AsFloatUnchecked(); + else + throw WrongArgumentTypeException(); +} + + +float ReceivedMessageArgument::AsFloatUnchecked() const +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + float f; + char c[4]; + } u; + + u.c[0] = argumentPtr_[3]; + u.c[1] = argumentPtr_[2]; + u.c[2] = argumentPtr_[1]; + u.c[3] = argumentPtr_[0]; + + return u.f; +#else + return *(float*)argument_; +#endif +} + + +char ReceivedMessageArgument::AsChar() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == CHAR_TYPE_TAG ) + return AsCharUnchecked(); + else + throw WrongArgumentTypeException(); +} + + +char ReceivedMessageArgument::AsCharUnchecked() const +{ + return (char)ToInt32( argumentPtr_ ); +} + + +uint32 ReceivedMessageArgument::AsRgbaColor() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == RGBA_COLOR_TYPE_TAG ) + return AsRgbaColorUnchecked(); + else + throw WrongArgumentTypeException(); +} + + +uint32 ReceivedMessageArgument::AsRgbaColorUnchecked() const +{ + return ToUInt32( argumentPtr_ ); +} + + +uint32 ReceivedMessageArgument::AsMidiMessage() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG ) + return AsMidiMessageUnchecked(); + else + throw WrongArgumentTypeException(); +} + + +uint32 ReceivedMessageArgument::AsMidiMessageUnchecked() const +{ + return ToUInt32( argumentPtr_ ); +} + + +int64 ReceivedMessageArgument::AsInt64() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == INT64_TYPE_TAG ) + return AsInt64Unchecked(); + else + throw WrongArgumentTypeException(); +} + + +int64 ReceivedMessageArgument::AsInt64Unchecked() const +{ + return ToInt64( argumentPtr_ ); +} + + +uint64 ReceivedMessageArgument::AsTimeTag() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == TIME_TAG_TYPE_TAG ) + return AsTimeTagUnchecked(); + else + throw WrongArgumentTypeException(); +} + + +uint64 ReceivedMessageArgument::AsTimeTagUnchecked() const +{ + return ToUInt64( argumentPtr_ ); +} + + +double ReceivedMessageArgument::AsDouble() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == DOUBLE_TYPE_TAG ) + return AsDoubleUnchecked(); + else + throw WrongArgumentTypeException(); +} + + +double ReceivedMessageArgument::AsDoubleUnchecked() const +{ +#ifdef OSC_HOST_LITTLE_ENDIAN + union{ + double d; + char c[8]; + } u; + + u.c[0] = argumentPtr_[7]; + u.c[1] = argumentPtr_[6]; + u.c[2] = argumentPtr_[5]; + u.c[3] = argumentPtr_[4]; + u.c[4] = argumentPtr_[3]; + u.c[5] = argumentPtr_[2]; + u.c[6] = argumentPtr_[1]; + u.c[7] = argumentPtr_[0]; + + return u.d; +#else + return *(double*)argument_; +#endif +} + + +const char* ReceivedMessageArgument::AsString() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == STRING_TYPE_TAG ) + return argumentPtr_; + else + throw WrongArgumentTypeException(); +} + + +const char* ReceivedMessageArgument::AsSymbol() const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == SYMBOL_TYPE_TAG ) + return argumentPtr_; + else + throw WrongArgumentTypeException(); +} + + +void ReceivedMessageArgument::AsBlob( const void*& data, osc_bundle_element_size_t& size ) const +{ + if( !typeTagPtr_ ) + throw MissingArgumentException(); + else if( *typeTagPtr_ == BLOB_TYPE_TAG ) + AsBlobUnchecked( data, size ); + else + throw WrongArgumentTypeException(); +} + + +void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size ) const +{ + // read blob size as an unsigned int then validate + osc_bundle_element_size_t sizeResult = (osc_bundle_element_size_t)ToUInt32( argumentPtr_ ); + if( !IsValidElementSizeValue(sizeResult) ) + throw MalformedMessageException("invalid blob size"); + + size = sizeResult; + data = (void*)(argumentPtr_+ osc::OSC_SIZEOF_INT32); +} + +std::size_t ReceivedMessageArgument::ComputeArrayItemCount() const +{ + // it is only valid to call ComputeArrayItemCount when the argument is the array start marker + if( !IsArrayBegin() ) + throw WrongArgumentTypeException(); + + std::size_t result = 0; + unsigned int level = 0; + const char *typeTag = typeTagPtr_ + 1; + + // iterate through all type tags. note that ReceivedMessage::Init + // has already checked that the message is well formed. + while( *typeTag ) { + switch( *typeTag++ ) { + case ARRAY_BEGIN_TYPE_TAG: + level += 1; + break; + + case ARRAY_END_TYPE_TAG: + if(level == 0) + return result; + level -= 1; + break; + + default: + if( level == 0 ) // only count items at level 0 + ++result; + } + } + + return result; +} + +//------------------------------------------------------------------------------ + +void ReceivedMessageArgumentIterator::Advance() +{ + if( !value_.typeTagPtr_ ) + return; + + switch( *value_.typeTagPtr_++ ){ + case '\0': + // don't advance past end + --value_.typeTagPtr_; + break; + + case TRUE_TYPE_TAG: + case FALSE_TYPE_TAG: + case NIL_TYPE_TAG: + case INFINITUM_TYPE_TAG: + + // zero length + break; + + case INT32_TYPE_TAG: + case FLOAT_TYPE_TAG: + case CHAR_TYPE_TAG: + case RGBA_COLOR_TYPE_TAG: + case MIDI_MESSAGE_TYPE_TAG: + + value_.argumentPtr_ += 4; + break; + + case INT64_TYPE_TAG: + case TIME_TAG_TYPE_TAG: + case DOUBLE_TYPE_TAG: + + value_.argumentPtr_ += 8; + break; + + case STRING_TYPE_TAG: + case SYMBOL_TYPE_TAG: + + // we use the unsafe function FindStr4End(char*) here because all of + // the arguments have already been validated in + // ReceivedMessage::Init() below. + + value_.argumentPtr_ = FindStr4End( value_.argumentPtr_ ); + break; + + case BLOB_TYPE_TAG: + { + // treat blob size as an unsigned int for the purposes of this calculation + uint32 blobSize = ToUInt32( value_.argumentPtr_ ); + value_.argumentPtr_ = value_.argumentPtr_ + osc::OSC_SIZEOF_INT32 + RoundUp4( blobSize ); + } + break; + + case ARRAY_BEGIN_TYPE_TAG: + case ARRAY_END_TYPE_TAG: + + // [ Indicates the beginning of an array. The tags following are for + // data in the Array until a close brace tag is reached. + // ] Indicates the end of an array. + + // zero length, don't advance argument ptr + break; + + default: // unknown type tag + // don't advance + --value_.typeTagPtr_; + break; + } +} + +//------------------------------------------------------------------------------ + +ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet ) + : addressPattern_( packet.Contents() ) +{ + Init( packet.Contents(), packet.Size() ); +} + + +ReceivedMessage::ReceivedMessage( const ReceivedBundleElement& bundleElement ) + : addressPattern_( bundleElement.Contents() ) +{ + Init( bundleElement.Contents(), bundleElement.Size() ); +} + + +bool ReceivedMessage::AddressPatternIsUInt32() const +{ + return (addressPattern_[0] == '\0'); +} + + +uint32 ReceivedMessage::AddressPatternAsUInt32() const +{ + return ToUInt32( addressPattern_ ); +} + + +void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size ) +{ + if( !IsValidElementSizeValue(size) ) + throw MalformedMessageException( "invalid message size" ); + + if( size == 0 ) + throw MalformedMessageException( "zero length messages not permitted" ); + + if( !IsMultipleOf4(size) ) + throw MalformedMessageException( "message size must be multiple of four" ); + + const char *end = message + size; + + typeTagsBegin_ = FindStr4End( addressPattern_, end ); + if( typeTagsBegin_ == 0 ){ + // address pattern was not terminated before end + throw MalformedMessageException( "unterminated address pattern" ); + } + + if( typeTagsBegin_ == end ){ + // message consists of only the address pattern - no arguments or type tags. + typeTagsBegin_ = 0; + typeTagsEnd_ = 0; + arguments_ = 0; + + }else{ + if( *typeTagsBegin_ != ',' ) + throw MalformedMessageException( "type tags not present" ); + + if( *(typeTagsBegin_ + 1) == '\0' ){ + // zero length type tags + typeTagsBegin_ = 0; + typeTagsEnd_ = 0; + arguments_ = 0; + + }else{ + // check that all arguments are present and well formed + + arguments_ = FindStr4End( typeTagsBegin_, end ); + if( arguments_ == 0 ){ + throw MalformedMessageException( "type tags were not terminated before end of message" ); + } + + ++typeTagsBegin_; // advance past initial ',' + + const char *typeTag = typeTagsBegin_; + const char *argument = arguments_; + unsigned int arrayLevel = 0; + + do{ + switch( *typeTag ){ + case TRUE_TYPE_TAG: + case FALSE_TYPE_TAG: + case NIL_TYPE_TAG: + case INFINITUM_TYPE_TAG: + // zero length + break; + + // [ Indicates the beginning of an array. The tags following are for + // data in the Array until a close brace tag is reached. + // ] Indicates the end of an array. + case ARRAY_BEGIN_TYPE_TAG: + ++arrayLevel; + // (zero length argument data) + break; + + case ARRAY_END_TYPE_TAG: + --arrayLevel; + // (zero length argument data) + break; + + case INT32_TYPE_TAG: + case FLOAT_TYPE_TAG: + case CHAR_TYPE_TAG: + case RGBA_COLOR_TYPE_TAG: + case MIDI_MESSAGE_TYPE_TAG: + + if( argument == end ) + throw MalformedMessageException( "arguments exceed message size" ); + argument += 4; + if( argument > end ) + throw MalformedMessageException( "arguments exceed message size" ); + break; + + case INT64_TYPE_TAG: + case TIME_TAG_TYPE_TAG: + case DOUBLE_TYPE_TAG: + + if( argument == end ) + throw MalformedMessageException( "arguments exceed message size" ); + argument += 8; + if( argument > end ) + throw MalformedMessageException( "arguments exceed message size" ); + break; + + case STRING_TYPE_TAG: + case SYMBOL_TYPE_TAG: + + if( argument == end ) + throw MalformedMessageException( "arguments exceed message size" ); + argument = FindStr4End( argument, end ); + if( argument == 0 ) + throw MalformedMessageException( "unterminated string argument" ); + break; + + case BLOB_TYPE_TAG: + { + if( argument + osc::OSC_SIZEOF_INT32 > end ) + MalformedMessageException( "arguments exceed message size" ); + + // treat blob size as an unsigned int for the purposes of this calculation + uint32 blobSize = ToUInt32( argument ); + argument = argument + osc::OSC_SIZEOF_INT32 + RoundUp4( blobSize ); + if( argument > end ) + MalformedMessageException( "arguments exceed message size" ); + } + break; + + default: + throw MalformedMessageException( "unknown type tag" ); + } + + }while( *++typeTag != '\0' ); + typeTagsEnd_ = typeTag; + + if( arrayLevel != 0 ) + throw MalformedMessageException( "array was not terminated before end of message (expected ']' end of array tag)" ); + } + + // These invariants should be guaranteed by the above code. + // we depend on them in the implementation of ArgumentCount() +#ifndef NDEBUG + std::ptrdiff_t argumentCount = typeTagsEnd_ - typeTagsBegin_; + assert( argumentCount >= 0 ); + assert( argumentCount <= OSC_INT32_MAX ); +#endif + } +} + +//------------------------------------------------------------------------------ + +ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet ) + : elementCount_( 0 ) +{ + Init( packet.Contents(), packet.Size() ); +} + + +ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement ) + : elementCount_( 0 ) +{ + Init( bundleElement.Contents(), bundleElement.Size() ); +} + + +void ReceivedBundle::Init( const char *bundle, osc_bundle_element_size_t size ) +{ + + if( !IsValidElementSizeValue(size) ) + throw MalformedBundleException( "invalid bundle size" ); + + if( size < 16 ) + throw MalformedBundleException( "packet too short for bundle" ); + + if( !IsMultipleOf4(size) ) + throw MalformedBundleException( "bundle size must be multiple of four" ); + + if( bundle[0] != '#' + || bundle[1] != 'b' + || bundle[2] != 'u' + || bundle[3] != 'n' + || bundle[4] != 'd' + || bundle[5] != 'l' + || bundle[6] != 'e' + || bundle[7] != '\0' ) + throw MalformedBundleException( "bad bundle address pattern" ); + + end_ = bundle + size; + + timeTag_ = bundle + 8; + + const char *p = timeTag_ + 8; + + while( p < end_ ){ + if( p + osc::OSC_SIZEOF_INT32 > end_ ) + throw MalformedBundleException( "packet too short for elementSize" ); + + // treat element size as an unsigned int for the purposes of this calculation + uint32 elementSize = ToUInt32( p ); + if( (elementSize & ((uint32)0x03)) != 0 ) + throw MalformedBundleException( "bundle element size must be multiple of four" ); + + p += osc::OSC_SIZEOF_INT32 + elementSize; + if( p > end_ ) + throw MalformedBundleException( "packet too short for bundle element" ); + + ++elementCount_; + } + + if( p != end_ ) + throw MalformedBundleException( "bundle contents " ); +} + + +uint64 ReceivedBundle::TimeTag() const +{ + return ToUInt64( timeTag_ ); +} + + +} // namespace osc + diff --git a/src/osc/oscPack/osc/OscReceivedElements.h b/src/osc/oscPack/osc/OscReceivedElements.h new file mode 100644 index 0000000..729938e --- /dev/null +++ b/src/osc/oscPack/osc/OscReceivedElements.h @@ -0,0 +1,548 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_OSCRECEIVEDELEMENTS_H +#define INCLUDED_OSCPACK_OSCRECEIVEDELEMENTS_H + +#include <cassert> +#include <cstddef> +#include <cstring> // size_t + +#include "OscTypes.h" +#include "OscException.h" + + +namespace osc{ + + +class MalformedPacketException : public Exception{ +public: + MalformedPacketException( const char *w="malformed packet" ) + : Exception( w ) {} +}; + +class MalformedMessageException : public Exception{ +public: + MalformedMessageException( const char *w="malformed message" ) + : Exception( w ) {} +}; + +class MalformedBundleException : public Exception{ +public: + MalformedBundleException( const char *w="malformed bundle" ) + : Exception( w ) {} +}; + +class WrongArgumentTypeException : public Exception{ +public: + WrongArgumentTypeException( const char *w="wrong argument type" ) + : Exception( w ) {} +}; + +class MissingArgumentException : public Exception{ +public: + MissingArgumentException( const char *w="missing argument" ) + : Exception( w ) {} +}; + +class ExcessArgumentException : public Exception{ +public: + ExcessArgumentException( const char *w="too many arguments" ) + : Exception( w ) {} +}; + + +class ReceivedPacket{ +public: + // Although the OSC spec is not entirely clear on this, we only support + // packets up to 0x7FFFFFFC bytes long (the maximum 4-byte aligned value + // representable by an int32). An exception will be raised if you pass a + // larger value to the ReceivedPacket() constructor. + + ReceivedPacket( const char *contents, osc_bundle_element_size_t size ) + : contents_( contents ) + , size_( ValidateSize(size) ) {} + + ReceivedPacket( const char *contents, std::size_t size ) + : contents_( contents ) + , size_( ValidateSize( (osc_bundle_element_size_t)size ) ) {} + +#if !(defined(__x86_64__) || defined(_M_X64)) + ReceivedPacket( const char *contents, int size ) + : contents_( contents ) + , size_( ValidateSize( (osc_bundle_element_size_t)size ) ) {} +#endif + + bool IsMessage() const { return !IsBundle(); } + bool IsBundle() const; + + osc_bundle_element_size_t Size() const { return size_; } + const char *Contents() const { return contents_; } + +private: + const char *contents_; + osc_bundle_element_size_t size_; + + static osc_bundle_element_size_t ValidateSize( osc_bundle_element_size_t size ) + { + // sanity check integer types declared in OscTypes.h + // you'll need to fix OscTypes.h if any of these asserts fail + assert( sizeof(osc::int32) == 4 ); + assert( sizeof(osc::uint32) == 4 ); + assert( sizeof(osc::int64) == 8 ); + assert( sizeof(osc::uint64) == 8 ); + + if( !IsValidElementSizeValue(size) ) + throw MalformedPacketException( "invalid packet size" ); + + if( size == 0 ) + throw MalformedPacketException( "zero length elements not permitted" ); + + if( !IsMultipleOf4(size) ) + throw MalformedPacketException( "element size must be multiple of four" ); + + return size; + } +}; + + +class ReceivedBundleElement{ +public: + ReceivedBundleElement( const char *sizePtr ) + : sizePtr_( sizePtr ) {} + + friend class ReceivedBundleElementIterator; + + bool IsMessage() const { return !IsBundle(); } + bool IsBundle() const; + + osc_bundle_element_size_t Size() const; + const char *Contents() const { return sizePtr_ + osc::OSC_SIZEOF_INT32; } + +private: + const char *sizePtr_; +}; + + +class ReceivedBundleElementIterator{ +public: + ReceivedBundleElementIterator( const char *sizePtr ) + : value_( sizePtr ) {} + + ReceivedBundleElementIterator operator++() + { + Advance(); + return *this; + } + + ReceivedBundleElementIterator operator++(int) + { + ReceivedBundleElementIterator old( *this ); + Advance(); + return old; + } + + const ReceivedBundleElement& operator*() const { return value_; } + + const ReceivedBundleElement* operator->() const { return &value_; } + + friend bool operator==(const ReceivedBundleElementIterator& lhs, + const ReceivedBundleElementIterator& rhs ); + +private: + ReceivedBundleElement value_; + + void Advance() { value_.sizePtr_ = value_.Contents() + value_.Size(); } + + bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const + { + return value_.sizePtr_ == rhs.value_.sizePtr_; + } +}; + +inline bool operator==(const ReceivedBundleElementIterator& lhs, + const ReceivedBundleElementIterator& rhs ) +{ + return lhs.IsEqualTo( rhs ); +} + +inline bool operator!=(const ReceivedBundleElementIterator& lhs, + const ReceivedBundleElementIterator& rhs ) +{ + return !( lhs == rhs ); +} + + +class ReceivedMessageArgument{ +public: + ReceivedMessageArgument( const char *typeTagPtr, const char *argumentPtr ) + : typeTagPtr_( typeTagPtr ) + , argumentPtr_( argumentPtr ) {} + + friend class ReceivedMessageArgumentIterator; + + char TypeTag() const { return *typeTagPtr_; } + + // the unchecked methods below don't check whether the argument actually + // is of the specified type. they should only be used if you've already + // checked the type tag or the associated IsType() method. + + bool IsBool() const + { return *typeTagPtr_ == TRUE_TYPE_TAG || *typeTagPtr_ == FALSE_TYPE_TAG; } + bool AsBool() const; + bool AsBoolUnchecked() const; + + bool IsNil() const { return *typeTagPtr_ == NIL_TYPE_TAG; } + bool IsInfinitum() const { return *typeTagPtr_ == INFINITUM_TYPE_TAG; } + + bool IsInt32() const { return *typeTagPtr_ == INT32_TYPE_TAG; } + int32 AsInt32() const; + int32 AsInt32Unchecked() const; + + bool IsFloat() const { return *typeTagPtr_ == FLOAT_TYPE_TAG; } + float AsFloat() const; + float AsFloatUnchecked() const; + + bool IsChar() const { return *typeTagPtr_ == CHAR_TYPE_TAG; } + char AsChar() const; + char AsCharUnchecked() const; + + bool IsRgbaColor() const { return *typeTagPtr_ == RGBA_COLOR_TYPE_TAG; } + uint32 AsRgbaColor() const; + uint32 AsRgbaColorUnchecked() const; + + bool IsMidiMessage() const { return *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG; } + uint32 AsMidiMessage() const; + uint32 AsMidiMessageUnchecked() const; + + bool IsInt64() const { return *typeTagPtr_ == INT64_TYPE_TAG; } + int64 AsInt64() const; + int64 AsInt64Unchecked() const; + + bool IsTimeTag() const { return *typeTagPtr_ == TIME_TAG_TYPE_TAG; } + uint64 AsTimeTag() const; + uint64 AsTimeTagUnchecked() const; + + bool IsDouble() const { return *typeTagPtr_ == DOUBLE_TYPE_TAG; } + double AsDouble() const; + double AsDoubleUnchecked() const; + + bool IsString() const { return *typeTagPtr_ == STRING_TYPE_TAG; } + const char* AsString() const; + const char* AsStringUnchecked() const { return argumentPtr_; } + + bool IsSymbol() const { return *typeTagPtr_ == SYMBOL_TYPE_TAG; } + const char* AsSymbol() const; + const char* AsSymbolUnchecked() const { return argumentPtr_; } + + bool IsBlob() const { return *typeTagPtr_ == BLOB_TYPE_TAG; } + void AsBlob( const void*& data, osc_bundle_element_size_t& size ) const; + void AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size ) const; + + bool IsArrayBegin() const { return *typeTagPtr_ == ARRAY_BEGIN_TYPE_TAG; } + bool IsArrayEnd() const { return *typeTagPtr_ == ARRAY_END_TYPE_TAG; } + // Calculate the number of top-level items in the array. Nested arrays count as one item. + // Only valid at array start. Will throw an exception if IsArrayStart() == false. + std::size_t ComputeArrayItemCount() const; + +private: + const char *typeTagPtr_; + const char *argumentPtr_; +}; + + +class ReceivedMessageArgumentIterator{ +public: + ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments ) + : value_( typeTags, arguments ) {} + + ReceivedMessageArgumentIterator operator++() + { + Advance(); + return *this; + } + + ReceivedMessageArgumentIterator operator++(int) + { + ReceivedMessageArgumentIterator old( *this ); + Advance(); + return old; + } + + const ReceivedMessageArgument& operator*() const { return value_; } + + const ReceivedMessageArgument* operator->() const { return &value_; } + + friend bool operator==(const ReceivedMessageArgumentIterator& lhs, + const ReceivedMessageArgumentIterator& rhs ); + +private: + ReceivedMessageArgument value_; + + void Advance(); + + bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const + { + return value_.typeTagPtr_ == rhs.value_.typeTagPtr_; + } +}; + +inline bool operator==(const ReceivedMessageArgumentIterator& lhs, + const ReceivedMessageArgumentIterator& rhs ) +{ + return lhs.IsEqualTo( rhs ); +} + +inline bool operator!=(const ReceivedMessageArgumentIterator& lhs, + const ReceivedMessageArgumentIterator& rhs ) +{ + return !( lhs == rhs ); +} + + +class ReceivedMessageArgumentStream{ + friend class ReceivedMessage; + ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin, + const ReceivedMessageArgumentIterator& end ) + : p_( begin ) + , end_( end ) {} + + ReceivedMessageArgumentIterator p_, end_; + +public: + + // end of stream + bool Eos() const { return p_ == end_; } + + ReceivedMessageArgumentStream& operator>>( bool& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs = (*p_++).AsBool(); + return *this; + } + + // not sure if it would be useful to stream Nil and Infinitum + // for now it's not possible + // same goes for array boundaries + + ReceivedMessageArgumentStream& operator>>( int32& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs = (*p_++).AsInt32(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( float& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs = (*p_++).AsFloat(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( char& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs = (*p_++).AsChar(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs.value = (*p_++).AsRgbaColor(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs.value = (*p_++).AsMidiMessage(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( int64& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs = (*p_++).AsInt64(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( TimeTag& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs.value = (*p_++).AsTimeTag(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( double& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs = (*p_++).AsDouble(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( Blob& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + (*p_++).AsBlob( rhs.data, rhs.size ); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( const char*& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs = (*p_++).AsString(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( Symbol& rhs ) + { + if( Eos() ) + throw MissingArgumentException(); + + rhs.value = (*p_++).AsSymbol(); + return *this; + } + + ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs ) + { + (void) rhs; // suppress unused parameter warning + + if( !Eos() ) + throw ExcessArgumentException(); + + return *this; + } +}; + + +class ReceivedMessage{ + void Init( const char *bundle, osc_bundle_element_size_t size ); +public: + explicit ReceivedMessage( const ReceivedPacket& packet ); + explicit ReceivedMessage( const ReceivedBundleElement& bundleElement ); + + const char *AddressPattern() const { return addressPattern_; } + + // Support for non-standard SuperCollider integer address patterns: + bool AddressPatternIsUInt32() const; + uint32 AddressPatternAsUInt32() const; + + uint32 ArgumentCount() const { return static_cast<uint32>(typeTagsEnd_ - typeTagsBegin_); } + + const char *TypeTags() const { return typeTagsBegin_; } + + + typedef ReceivedMessageArgumentIterator const_iterator; + + ReceivedMessageArgumentIterator ArgumentsBegin() const + { + return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ ); + } + + ReceivedMessageArgumentIterator ArgumentsEnd() const + { + return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 ); + } + + ReceivedMessageArgumentStream ArgumentStream() const + { + return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() ); + } + +private: + const char *addressPattern_; + const char *typeTagsBegin_; + const char *typeTagsEnd_; + const char *arguments_; +}; + + +class ReceivedBundle{ + void Init( const char *message, osc_bundle_element_size_t size ); +public: + explicit ReceivedBundle( const ReceivedPacket& packet ); + explicit ReceivedBundle( const ReceivedBundleElement& bundleElement ); + + uint64 TimeTag() const; + + uint32 ElementCount() const { return elementCount_; } + + typedef ReceivedBundleElementIterator const_iterator; + + ReceivedBundleElementIterator ElementsBegin() const + { + return ReceivedBundleElementIterator( timeTag_ + 8 ); + } + + ReceivedBundleElementIterator ElementsEnd() const + { + return ReceivedBundleElementIterator( end_ ); + } + +private: + const char *timeTag_; + const char *end_; + uint32 elementCount_; +}; + + +} // namespace osc + + +#endif /* INCLUDED_OSCPACK_OSCRECEIVEDELEMENTS_H */ diff --git a/src/osc/oscPack/osc/OscTypes.cpp b/src/osc/oscPack/osc/OscTypes.cpp new file mode 100644 index 0000000..51616d5 --- /dev/null +++ b/src/osc/oscPack/osc/OscTypes.cpp @@ -0,0 +1,52 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#include "OscTypes.h" + +namespace osc{ + +BundleInitiator BeginBundleImmediate(1); +BundleTerminator EndBundle; +MessageTerminator EndMessage; +NilType OscNil; +#ifndef _OBJC_OBJC_H_ +NilType Nil; // Objective-C defines Nil. so our Nil is deprecated. use OscNil instead +#endif +InfinitumType Infinitum; +ArrayInitiator BeginArray; +ArrayTerminator EndArray; + +} // namespace osc diff --git a/src/osc/oscPack/osc/OscTypes.h b/src/osc/oscPack/osc/OscTypes.h new file mode 100644 index 0000000..005524f --- /dev/null +++ b/src/osc/oscPack/osc/OscTypes.h @@ -0,0 +1,240 @@ +/* + oscpack -- Open Sound Control (OSC) packet manipulation library + http://www.rossbencina.com/code/oscpack + + Copyright (c) 2004-2013 Ross Bencina <rossb@audiomulch.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + The text above constitutes the entire oscpack license; however, + the oscpack developer(s) also make the following non-binding requests: + + Any person wishing to distribute modifications to the Software is + requested to send the modifications to the original developer so that + they can be incorporated into the canonical version. It is also + requested that these non-binding requests be included whenever the + above license is reproduced. +*/ +#ifndef INCLUDED_OSCPACK_OSCTYPES_H +#define INCLUDED_OSCPACK_OSCTYPES_H + + +namespace osc{ + +// basic types + +#if defined(__BORLANDC__) || defined(_MSC_VER) + +typedef __int64 int64; +typedef unsigned __int64 uint64; + +#elif defined(__x86_64__) || defined(_M_X64) + +typedef long int64; +typedef unsigned long uint64; + +#else + +typedef long long int64; +typedef unsigned long long uint64; + +#endif + + + +#if defined(__x86_64__) || defined(_M_X64) + +typedef signed int int32; +typedef unsigned int uint32; + +#else + +typedef signed long int32; +typedef unsigned long uint32; + +#endif + + +enum ValueTypeSizes{ + OSC_SIZEOF_INT32 = 4, + OSC_SIZEOF_UINT32 = 4, + OSC_SIZEOF_INT64 = 8, + OSC_SIZEOF_UINT64 = 8, +}; + + +// osc_bundle_element_size_t is used for the size of bundle elements and blobs +// the OSC spec specifies these as int32 (signed) but we ensure that they +// are always positive since negative field sizes make no sense. + +typedef int32 osc_bundle_element_size_t; + +enum { + OSC_INT32_MAX = 0x7FFFFFFF, + + // Element sizes are specified to be int32, and are always rounded up to nearest + // multiple of 4. Therefore their values can't be greater than 0x7FFFFFFC. + OSC_BUNDLE_ELEMENT_SIZE_MAX = 0x7FFFFFFC +}; + + +inline bool IsValidElementSizeValue( osc_bundle_element_size_t x ) +{ + // sizes may not be negative or exceed OSC_BUNDLE_ELEMENT_SIZE_MAX + return x >= 0 && x <= OSC_BUNDLE_ELEMENT_SIZE_MAX; +} + + +inline bool IsMultipleOf4( osc_bundle_element_size_t x ) +{ + return (x & ((osc_bundle_element_size_t)0x03)) == 0; +} + + +enum TypeTagValues { + TRUE_TYPE_TAG = 'T', + FALSE_TYPE_TAG = 'F', + NIL_TYPE_TAG = 'N', + INFINITUM_TYPE_TAG = 'I', + INT32_TYPE_TAG = 'i', + FLOAT_TYPE_TAG = 'f', + CHAR_TYPE_TAG = 'c', + RGBA_COLOR_TYPE_TAG = 'r', + MIDI_MESSAGE_TYPE_TAG = 'm', + INT64_TYPE_TAG = 'h', + TIME_TAG_TYPE_TAG = 't', + DOUBLE_TYPE_TAG = 'd', + STRING_TYPE_TAG = 's', + SYMBOL_TYPE_TAG = 'S', + BLOB_TYPE_TAG = 'b', + ARRAY_BEGIN_TYPE_TAG = '[', + ARRAY_END_TYPE_TAG = ']' +}; + + + +// i/o manipulators used for streaming interfaces + +struct BundleInitiator{ + explicit BundleInitiator( uint64 timeTag_ ) : timeTag( timeTag_ ) {} + uint64 timeTag; +}; + +extern BundleInitiator BeginBundleImmediate; + +inline BundleInitiator BeginBundle( uint64 timeTag=1 ) +{ + return BundleInitiator(timeTag); +} + + +struct BundleTerminator{ +}; + +extern BundleTerminator EndBundle; + +struct BeginMessage{ + explicit BeginMessage( const char *addressPattern_ ) : addressPattern( addressPattern_ ) {} + const char *addressPattern; +}; + +struct MessageTerminator{ +}; + +extern MessageTerminator EndMessage; + + +// osc specific types. they are defined as structs so they can be used +// as separately identifiable types with the streaming operators. + +struct NilType{ +}; + +extern NilType OscNil; + +#ifndef _OBJC_OBJC_H_ +extern NilType Nil; // Objective-C defines Nil. so our Nil is deprecated. use OscNil instead +#endif + +struct InfinitumType{ +}; + +extern InfinitumType Infinitum; + +struct RgbaColor{ + RgbaColor() {} + explicit RgbaColor( uint32 value_ ) : value( value_ ) {} + uint32 value; + + operator uint32() const { return value; } +}; + + +struct MidiMessage{ + MidiMessage() {} + explicit MidiMessage( uint32 value_ ) : value( value_ ) {} + uint32 value; + + operator uint32() const { return value; } +}; + + +struct TimeTag{ + TimeTag() {} + explicit TimeTag( uint64 value_ ) : value( value_ ) {} + uint64 value; + + operator uint64() const { return value; } +}; + + +struct Symbol{ + Symbol() {} + explicit Symbol( const char* value_ ) : value( value_ ) {} + const char* value; + + operator const char *() const { return value; } +}; + + +struct Blob{ + Blob() {} + explicit Blob( const void* data_, osc_bundle_element_size_t size_ ) + : data( data_ ), size( size_ ) {} + const void* data; + osc_bundle_element_size_t size; +}; + +struct ArrayInitiator{ +}; + +extern ArrayInitiator BeginArray; + +struct ArrayTerminator{ +}; + +extern ArrayTerminator EndArray; + +} // namespace osc + + +#endif /* INCLUDED_OSCPACK_OSCTYPES_H */ diff --git a/src/tags b/src/tags new file mode 100644 index 0000000..1d02e6b --- /dev/null +++ b/src/tags @@ -0,0 +1,2475 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ +!_TAG_PROGRAM_NAME Exuberant Ctags // +!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ +!_TAG_PROGRAM_VERSION 5.9~svn20110310 // +ACCESSIBILITY modules/Attribute.hpp /^ enum ACCESSIBILITY {HIDDEN, OUTPUT, LOCAL, GLOBAL};$/;" g class:Attribute +ACTION_ATTRIBUTE modules/Attribute.hpp /^ ACTION_ATTRIBUTE, $/;" e enum:Attribute::TYPE +ACTION_FLOAT_ATTRIBUTE modules/Attribute.hpp /^ ACTION_FLOAT_ATTRIBUTE,$/;" e enum:Attribute::TYPE +ACTION_INT_ATTRIBUTE modules/Attribute.hpp /^ ACTION_INT_ATTRIBUTE,$/;" e enum:Attribute::TYPE +ACTION_STRING_ATTRIBUTE modules/Attribute.hpp /^ ACTION_STRING_ATTRIBUTE,$/;" e enum:Attribute::TYPE +ADDRESS_AND_PORT_STRING_LENGTH osc/oscPack/ip/IpEndpointName.h /^ enum { ADDRESS_AND_PORT_STRING_LENGTH=23};$/;" e enum:IpEndpointName::__anon4 +ADDRESS_STRING_LENGTH osc/oscPack/ip/IpEndpointName.h /^ enum { ADDRESS_STRING_LENGTH=17 };$/;" e enum:IpEndpointName::__anon3 +AI_CONFIG_PP_SBP_REMOVE modules/ModelModule.cpp 23;" d file: +ANY_ADDRESS osc/oscPack/ip/IpEndpointName.h /^ static const unsigned long ANY_ADDRESS = 0xFFFFFFFF;$/;" m class:IpEndpointName +ANY_PORT osc/oscPack/ip/IpEndpointName.h /^ static const int ANY_PORT = -1;$/;" m class:IpEndpointName +ARRAY_BEGIN_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ ARRAY_BEGIN_TYPE_TAG = '[',$/;" e enum:osc::TypeTagValues +ARRAY_END_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ ARRAY_END_TYPE_TAG = ']'$/;" e enum:osc::TypeTagValues +ActionCallback modules/Attribute.hpp /^ typedef void (ActionCallback) (Module*);$/;" t class:Attribute +AddressAndPortAsString osc/oscPack/ip/IpEndpointName.cpp /^void IpEndpointName::AddressAndPortAsString( char *s ) const$/;" f class:IpEndpointName +AddressAndPortAsString osc/oscPack/ip/IpEndpointName.h /^ void AddressAndPortAsString( char *s ) const;$/;" p class:IpEndpointName +AddressAsString osc/oscPack/ip/IpEndpointName.cpp /^void IpEndpointName::AddressAsString( char *s ) const$/;" f class:IpEndpointName +AddressAsString osc/oscPack/ip/IpEndpointName.h /^ void AddressAsString( char *s ) const;$/;" p class:IpEndpointName +AddressPattern osc/oscPack/osc/OscReceivedElements.h /^ const char *AddressPattern() const { return addressPattern_; }$/;" f class:osc::ReceivedMessage +AddressPatternAsUInt32 osc/oscPack/osc/OscReceivedElements.cpp /^uint32 ReceivedMessage::AddressPatternAsUInt32() const$/;" f class:osc::ReceivedMessage +AddressPatternAsUInt32 osc/oscPack/osc/OscReceivedElements.h /^ uint32 AddressPatternAsUInt32() const;$/;" p class:osc::ReceivedMessage +AddressPatternIsUInt32 osc/oscPack/osc/OscReceivedElements.cpp /^bool ReceivedMessage::AddressPatternIsUInt32() const$/;" f class:osc::ReceivedMessage +AddressPatternIsUInt32 osc/oscPack/osc/OscReceivedElements.h /^ bool AddressPatternIsUInt32() const;$/;" p class:osc::ReceivedMessage +Advance osc/oscPack/osc/OscReceivedElements.cpp /^void ReceivedMessageArgumentIterator::Advance()$/;" f class:osc::ReceivedMessageArgumentIterator +Advance osc/oscPack/osc/OscReceivedElements.h /^ void Advance() { value_.sizePtr_ = value_.Contents() + value_.Size(); }$/;" f class:osc::ReceivedBundleElementIterator +Advance osc/oscPack/osc/OscReceivedElements.h /^ void Advance();$/;" p class:osc::ReceivedMessageArgumentIterator +ArgumentCount osc/oscPack/osc/OscReceivedElements.h /^ uint32 ArgumentCount() const { return static_cast<uint32>(typeTagsEnd_ - typeTagsBegin_); }$/;" f class:osc::ReceivedMessage +ArgumentStream osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream ArgumentStream() const$/;" f class:osc::ReceivedMessage +ArgumentsBegin osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentIterator ArgumentsBegin() const$/;" f class:osc::ReceivedMessage +ArgumentsEnd osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentIterator ArgumentsEnd() const$/;" f class:osc::ReceivedMessage +ArrayInitiator osc/oscPack/osc/OscTypes.h /^struct ArrayInitiator{$/;" s namespace:osc +ArrayTerminator osc/oscPack/osc/OscTypes.h /^struct ArrayTerminator{$/;" s namespace:osc +ArucoTracker modules/DepthCamModule.hpp /^class ArucoTracker : public Tracker {$/;" c +AsBlob osc/oscPack/osc/OscReceivedElements.cpp /^void ReceivedMessageArgument::AsBlob( const void*& data, osc_bundle_element_size_t& size ) const$/;" f class:osc::ReceivedMessageArgument +AsBlob osc/oscPack/osc/OscReceivedElements.h /^ void AsBlob( const void*& data, osc_bundle_element_size_t& size ) const;$/;" p class:osc::ReceivedMessageArgument +AsBlobUnchecked osc/oscPack/osc/OscReceivedElements.cpp /^void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size ) const$/;" f class:osc::ReceivedMessageArgument +AsBlobUnchecked osc/oscPack/osc/OscReceivedElements.h /^ void AsBlobUnchecked( const void*& data, osc_bundle_element_size_t& size ) const;$/;" p class:osc::ReceivedMessageArgument +AsBool osc/oscPack/osc/OscReceivedElements.cpp /^bool ReceivedMessageArgument::AsBool() const$/;" f class:osc::ReceivedMessageArgument +AsBool osc/oscPack/osc/OscReceivedElements.h /^ bool AsBool() const;$/;" p class:osc::ReceivedMessageArgument +AsBoolUnchecked osc/oscPack/osc/OscReceivedElements.cpp /^bool ReceivedMessageArgument::AsBoolUnchecked() const$/;" f class:osc::ReceivedMessageArgument +AsBoolUnchecked osc/oscPack/osc/OscReceivedElements.h /^ bool AsBoolUnchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsChar osc/oscPack/osc/OscReceivedElements.cpp /^char ReceivedMessageArgument::AsChar() const$/;" f class:osc::ReceivedMessageArgument +AsChar osc/oscPack/osc/OscReceivedElements.h /^ char AsChar() const;$/;" p class:osc::ReceivedMessageArgument +AsCharUnchecked osc/oscPack/osc/OscReceivedElements.cpp /^char ReceivedMessageArgument::AsCharUnchecked() const$/;" f class:osc::ReceivedMessageArgument +AsCharUnchecked osc/oscPack/osc/OscReceivedElements.h /^ char AsCharUnchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsDouble osc/oscPack/osc/OscReceivedElements.cpp /^double ReceivedMessageArgument::AsDouble() const$/;" f class:osc::ReceivedMessageArgument +AsDouble osc/oscPack/osc/OscReceivedElements.h /^ double AsDouble() const;$/;" p class:osc::ReceivedMessageArgument +AsDoubleUnchecked osc/oscPack/osc/OscReceivedElements.cpp /^double ReceivedMessageArgument::AsDoubleUnchecked() const$/;" f class:osc::ReceivedMessageArgument +AsDoubleUnchecked osc/oscPack/osc/OscReceivedElements.h /^ double AsDoubleUnchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsFloat osc/oscPack/osc/OscReceivedElements.cpp /^float ReceivedMessageArgument::AsFloat() const$/;" f class:osc::ReceivedMessageArgument +AsFloat osc/oscPack/osc/OscReceivedElements.h /^ float AsFloat() const;$/;" p class:osc::ReceivedMessageArgument +AsFloatUnchecked osc/oscPack/osc/OscReceivedElements.cpp /^float ReceivedMessageArgument::AsFloatUnchecked() const$/;" f class:osc::ReceivedMessageArgument +AsFloatUnchecked osc/oscPack/osc/OscReceivedElements.h /^ float AsFloatUnchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsInt32 osc/oscPack/osc/OscReceivedElements.cpp /^int32 ReceivedMessageArgument::AsInt32() const$/;" f class:osc::ReceivedMessageArgument +AsInt32 osc/oscPack/osc/OscReceivedElements.h /^ int32 AsInt32() const;$/;" p class:osc::ReceivedMessageArgument +AsInt32Unchecked osc/oscPack/osc/OscReceivedElements.cpp /^int32 ReceivedMessageArgument::AsInt32Unchecked() const$/;" f class:osc::ReceivedMessageArgument +AsInt32Unchecked osc/oscPack/osc/OscReceivedElements.h /^ int32 AsInt32Unchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsInt64 osc/oscPack/osc/OscReceivedElements.cpp /^int64 ReceivedMessageArgument::AsInt64() const$/;" f class:osc::ReceivedMessageArgument +AsInt64 osc/oscPack/osc/OscReceivedElements.h /^ int64 AsInt64() const;$/;" p class:osc::ReceivedMessageArgument +AsInt64Unchecked osc/oscPack/osc/OscReceivedElements.cpp /^int64 ReceivedMessageArgument::AsInt64Unchecked() const$/;" f class:osc::ReceivedMessageArgument +AsInt64Unchecked osc/oscPack/osc/OscReceivedElements.h /^ int64 AsInt64Unchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsMidiMessage osc/oscPack/osc/OscReceivedElements.cpp /^uint32 ReceivedMessageArgument::AsMidiMessage() const$/;" f class:osc::ReceivedMessageArgument +AsMidiMessage osc/oscPack/osc/OscReceivedElements.h /^ uint32 AsMidiMessage() const;$/;" p class:osc::ReceivedMessageArgument +AsMidiMessageUnchecked osc/oscPack/osc/OscReceivedElements.cpp /^uint32 ReceivedMessageArgument::AsMidiMessageUnchecked() const$/;" f class:osc::ReceivedMessageArgument +AsMidiMessageUnchecked osc/oscPack/osc/OscReceivedElements.h /^ uint32 AsMidiMessageUnchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsRgbaColor osc/oscPack/osc/OscReceivedElements.cpp /^uint32 ReceivedMessageArgument::AsRgbaColor() const$/;" f class:osc::ReceivedMessageArgument +AsRgbaColor osc/oscPack/osc/OscReceivedElements.h /^ uint32 AsRgbaColor() const;$/;" p class:osc::ReceivedMessageArgument +AsRgbaColorUnchecked osc/oscPack/osc/OscReceivedElements.cpp /^uint32 ReceivedMessageArgument::AsRgbaColorUnchecked() const$/;" f class:osc::ReceivedMessageArgument +AsRgbaColorUnchecked osc/oscPack/osc/OscReceivedElements.h /^ uint32 AsRgbaColorUnchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsString osc/oscPack/osc/OscReceivedElements.cpp /^const char* ReceivedMessageArgument::AsString() const$/;" f class:osc::ReceivedMessageArgument +AsString osc/oscPack/osc/OscReceivedElements.h /^ const char* AsString() const;$/;" p class:osc::ReceivedMessageArgument +AsStringUnchecked osc/oscPack/osc/OscReceivedElements.h /^ const char* AsStringUnchecked() const { return argumentPtr_; }$/;" f class:osc::ReceivedMessageArgument +AsSymbol osc/oscPack/osc/OscReceivedElements.cpp /^const char* ReceivedMessageArgument::AsSymbol() const$/;" f class:osc::ReceivedMessageArgument +AsSymbol osc/oscPack/osc/OscReceivedElements.h /^ const char* AsSymbol() const;$/;" p class:osc::ReceivedMessageArgument +AsSymbolUnchecked osc/oscPack/osc/OscReceivedElements.h /^ const char* AsSymbolUnchecked() const { return argumentPtr_; }$/;" f class:osc::ReceivedMessageArgument +AsTimeTag osc/oscPack/osc/OscReceivedElements.cpp /^uint64 ReceivedMessageArgument::AsTimeTag() const$/;" f class:osc::ReceivedMessageArgument +AsTimeTag osc/oscPack/osc/OscReceivedElements.h /^ uint64 AsTimeTag() const;$/;" p class:osc::ReceivedMessageArgument +AsTimeTagUnchecked osc/oscPack/osc/OscReceivedElements.cpp /^uint64 ReceivedMessageArgument::AsTimeTagUnchecked() const$/;" f class:osc::ReceivedMessageArgument +AsTimeTagUnchecked osc/oscPack/osc/OscReceivedElements.h /^ uint64 AsTimeTagUnchecked() const;$/;" p class:osc::ReceivedMessageArgument +AsynchronousBreak osc/oscPack/ip/UdpSocket.h /^ void AsynchronousBreak() { mux_.AsynchronousBreak(); }$/;" f class:UdpListeningReceiveSocket +AsynchronousBreak osc/oscPack/ip/UdpSocket.h /^ void AsynchronousBreak(); \/\/ call this from another thread or signal handler to exit the Run() state$/;" p class:SocketReceiveMultiplexer +AsynchronousBreak osc/oscPack/ip/posix/UdpSocket.cpp /^ void AsynchronousBreak()$/;" f class:SocketReceiveMultiplexer::Implementation +AsynchronousBreak osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::AsynchronousBreak()$/;" f class:SocketReceiveMultiplexer +AsynchronousBreak osc/oscPack/ip/win32/UdpSocket.cpp /^ void AsynchronousBreak()$/;" f class:SocketReceiveMultiplexer::Implementation +AsynchronousBreak osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::AsynchronousBreak()$/;" f class:SocketReceiveMultiplexer +AttachPeriodicTimerListener osc/oscPack/ip/UdpSocket.h /^ void AttachPeriodicTimerListener($/;" p class:SocketReceiveMultiplexer +AttachPeriodicTimerListener osc/oscPack/ip/UdpSocket.h /^ void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener );$/;" p class:SocketReceiveMultiplexer +AttachPeriodicTimerListener osc/oscPack/ip/posix/UdpSocket.cpp /^ void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +AttachPeriodicTimerListener osc/oscPack/ip/posix/UdpSocket.cpp /^ void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +AttachPeriodicTimerListener osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )$/;" f class:SocketReceiveMultiplexer +AttachPeriodicTimerListener osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )$/;" f class:SocketReceiveMultiplexer +AttachPeriodicTimerListener osc/oscPack/ip/win32/UdpSocket.cpp /^ void AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +AttachPeriodicTimerListener osc/oscPack/ip/win32/UdpSocket.cpp /^ void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +AttachPeriodicTimerListener osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener )$/;" f class:SocketReceiveMultiplexer +AttachPeriodicTimerListener osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener )$/;" f class:SocketReceiveMultiplexer +AttachSocketListener osc/oscPack/ip/UdpSocket.h /^ void AttachSocketListener( UdpSocket *socket, PacketListener *listener );$/;" p class:SocketReceiveMultiplexer +AttachSocketListener osc/oscPack/ip/posix/UdpSocket.cpp /^ void AttachSocketListener( UdpSocket *socket, PacketListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +AttachSocketListener osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener )$/;" f class:SocketReceiveMultiplexer +AttachSocketListener osc/oscPack/ip/win32/UdpSocket.cpp /^ void AttachSocketListener( UdpSocket *socket, PacketListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +AttachSocketListener osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::AttachSocketListener( UdpSocket *socket, PacketListener *listener )$/;" f class:SocketReceiveMultiplexer +AttachedTimerListener osc/oscPack/ip/posix/UdpSocket.cpp /^ AttachedTimerListener( int id, int p, TimerListener *tl )$/;" f struct:AttachedTimerListener +AttachedTimerListener osc/oscPack/ip/posix/UdpSocket.cpp /^struct AttachedTimerListener{$/;" s file: +AttachedTimerListener osc/oscPack/ip/win32/UdpSocket.cpp /^ AttachedTimerListener( int id, int p, TimerListener *tl )$/;" f struct:AttachedTimerListener +AttachedTimerListener osc/oscPack/ip/win32/UdpSocket.cpp /^struct AttachedTimerListener{$/;" s file: +Attribute modules/Attribute.hpp /^ Attribute(const std::string& name, const TYPE& type, $/;" f class:Attribute +Attribute modules/Attribute.hpp /^class Attribute {$/;" c +AttributeWidget gui/AttributeWidget.cpp /^AttributeWidget::AttributeWidget(int x, int y, $/;" f class:AttributeWidget +AttributeWidget gui/AttributeWidget.hpp /^ AttributeWidget(int x, int y, int w, int h, Attribute* attribute);$/;" p class:AttributeWidget +AttributeWidget gui/AttributeWidget.hpp /^class AttributeWidget : public Fl_Group {$/;" c +AttributeWidget_h gui/AttributeWidget.hpp 24;" d +Attribute_h modules/Attribute.hpp 25;" d +BACKGROUND Reveal.hpp /^ CAMFILTER, CAMCONTOURTHRESH, CAMMARKERS, MARKTEX, BACKGROUND,$/;" e enum:Reveal::REVIL_UNIFORM +BBOXLOCALSIZE Reveal.hpp /^ BBOXMIN, BBOXSIZE, BBOXROT, BBOXLOCALSIZE, $/;" e enum:Reveal::REVIL_UNIFORM +BBOXMIN Reveal.hpp /^ BBOXMIN, BBOXSIZE, BBOXROT, BBOXLOCALSIZE, $/;" e enum:Reveal::REVIL_UNIFORM +BBOXROT Reveal.hpp /^ BBOXMIN, BBOXSIZE, BBOXROT, BBOXLOCALSIZE, $/;" e enum:Reveal::REVIL_UNIFORM +BBOXSIZE Reveal.hpp /^ BBOXMIN, BBOXSIZE, BBOXROT, BBOXLOCALSIZE, $/;" e enum:Reveal::REVIL_UNIFORM +BLOB_ATTRIBUTE modules/Attribute.hpp /^ BLOB_ATTRIBUTE};$/;" e enum:Attribute::TYPE +BLOB_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ BLOB_TYPE_TAG = 'b',$/;" e enum:osc::TypeTagValues +BOOL_ATTRIBUTE modules/Attribute.hpp /^ BOOL_ATTRIBUTE, $/;" e enum:Attribute::TYPE +BeginArray osc/oscPack/osc/OscTypes.cpp /^ArrayInitiator BeginArray;$/;" m namespace:osc file: +BeginBundle osc/oscPack/osc/OscTypes.h /^inline BundleInitiator BeginBundle( uint64 timeTag=1 )$/;" f namespace:osc +BeginElement osc/oscPack/osc/OscOutboundPacketStream.cpp /^char *OutboundPacketStream::BeginElement( char *beginPtr )$/;" f class:osc::OutboundPacketStream +BeginElement osc/oscPack/osc/OscOutboundPacketStream.h /^ char *BeginElement( char *beginPtr );$/;" p class:osc::OutboundPacketStream +BeginMessage osc/oscPack/osc/OscTypes.h /^ explicit BeginMessage( const char *addressPattern_ ) : addressPattern( addressPattern_ ) {}$/;" f struct:osc::BeginMessage +BeginMessage osc/oscPack/osc/OscTypes.h /^struct BeginMessage{$/;" s namespace:osc +Bind osc/oscPack/ip/UdpSocket.h /^ void Bind( const IpEndpointName& localEndpoint );$/;" p class:UdpSocket +Bind osc/oscPack/ip/posix/UdpSocket.cpp /^ void Bind( const IpEndpointName& localEndpoint )$/;" f class:UdpSocket::Implementation +Bind osc/oscPack/ip/posix/UdpSocket.cpp /^void UdpSocket::Bind( const IpEndpointName& localEndpoint )$/;" f class:UdpSocket +Bind osc/oscPack/ip/win32/UdpSocket.cpp /^ void Bind( const IpEndpointName& localEndpoint )$/;" f class:UdpSocket::Implementation +Bind osc/oscPack/ip/win32/UdpSocket.cpp /^void UdpSocket::Bind( const IpEndpointName& localEndpoint )$/;" f class:UdpSocket +Blob osc/oscPack/osc/OscTypes.h /^ Blob() {}$/;" f struct:osc::Blob +Blob osc/oscPack/osc/OscTypes.h /^ explicit Blob( const void* data_, osc_bundle_element_size_t size_ )$/;" f struct:osc::Blob +Blob osc/oscPack/osc/OscTypes.h /^struct Blob{$/;" s namespace:osc +BlobCallback modules/Attribute.hpp /^ typedef void (BlobCallback) (Module*, const std::string&, void*);$/;" t class:Attribute +BoolCallback modules/Attribute.hpp /^ typedef void (BoolCallback) (Module*,const std::vector<bool>&);$/;" t class:Attribute +BoxGeometry geoms/BoxGeometry.cpp /^BoxGeometry::BoxGeometry(): Geometry() {$/;" f class:BoxGeometry +BoxGeometry geoms/BoxGeometry.hpp /^ BoxGeometry();$/;" p class:BoxGeometry +BoxGeometry geoms/BoxGeometry.hpp /^class BoxGeometry : public Geometry {$/;" c +BoxGeometry_h geoms/BoxGeometry.hpp 25;" d +Break osc/oscPack/ip/UdpSocket.h /^ void Break() { mux_.Break(); }$/;" f class:UdpListeningReceiveSocket +Break osc/oscPack/ip/UdpSocket.h /^ void Break(); \/\/ call this from a listener to exit once the listener returns$/;" p class:SocketReceiveMultiplexer +Break osc/oscPack/ip/posix/UdpSocket.cpp /^ void Break()$/;" f class:SocketReceiveMultiplexer::Implementation +Break osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::Break()$/;" f class:SocketReceiveMultiplexer +Break osc/oscPack/ip/win32/UdpSocket.cpp /^ void Break()$/;" f class:SocketReceiveMultiplexer::Implementation +Break osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::Break()$/;" f class:SocketReceiveMultiplexer +BundleInitiator osc/oscPack/osc/OscTypes.h /^ explicit BundleInitiator( uint64 timeTag_ ) : timeTag( timeTag_ ) {}$/;" f struct:osc::BundleInitiator +BundleInitiator osc/oscPack/osc/OscTypes.h /^struct BundleInitiator{$/;" s namespace:osc +BundleNotInProgressException osc/oscPack/osc/OscOutboundPacketStream.h /^ BundleNotInProgressException($/;" f class:osc::BundleNotInProgressException +BundleNotInProgressException osc/oscPack/osc/OscOutboundPacketStream.h /^class BundleNotInProgressException : public Exception{$/;" c namespace:osc +BundleTerminator osc/oscPack/osc/OscTypes.h /^struct BundleTerminator{$/;" s namespace:osc +CALIBPROG Reveal.hpp /^ PREVIEWPROG, SLICEPROG, SELECTPROG, RENDERPROG, CALIBPROG$/;" e enum:Reveal::REVIL_PROGRAM +CAMCONTOURTHRESH Reveal.hpp /^ CAMFILTER, CAMCONTOURTHRESH, CAMMARKERS, MARKTEX, BACKGROUND,$/;" e enum:Reveal::REVIL_UNIFORM +CAMFILTER Reveal.hpp /^ CAMFILTER, CAMCONTOURTHRESH, CAMMARKERS, MARKTEX, BACKGROUND,$/;" e enum:Reveal::REVIL_UNIFORM +CAMMARKERS Reveal.hpp /^ CAMFILTER, CAMCONTOURTHRESH, CAMMARKERS, MARKTEX, BACKGROUND,$/;" e enum:Reveal::REVIL_UNIFORM +CAMTEX1 Reveal.hpp /^ CAMTEX1, CAMTEX2, CAMXRESO, CAMYRESO, CAMXZFACTOR, CAMYZFACTOR, $/;" e enum:Reveal::REVIL_UNIFORM +CAMTEX2 Reveal.hpp /^ CAMTEX1, CAMTEX2, CAMXRESO, CAMYRESO, CAMXZFACTOR, CAMYZFACTOR, $/;" e enum:Reveal::REVIL_UNIFORM +CAMXRESO Reveal.hpp /^ CAMTEX1, CAMTEX2, CAMXRESO, CAMYRESO, CAMXZFACTOR, CAMYZFACTOR, $/;" e enum:Reveal::REVIL_UNIFORM +CAMXZFACTOR Reveal.hpp /^ CAMTEX1, CAMTEX2, CAMXRESO, CAMYRESO, CAMXZFACTOR, CAMYZFACTOR, $/;" e enum:Reveal::REVIL_UNIFORM +CAMYRESO Reveal.hpp /^ CAMTEX1, CAMTEX2, CAMXRESO, CAMYRESO, CAMXZFACTOR, CAMYZFACTOR, $/;" e enum:Reveal::REVIL_UNIFORM +CAMYZFACTOR Reveal.hpp /^ CAMTEX1, CAMTEX2, CAMXRESO, CAMYRESO, CAMXZFACTOR, CAMYZFACTOR, $/;" e enum:Reveal::REVIL_UNIFORM +CHAR_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ CHAR_TYPE_TAG = 'c',$/;" e enum:osc::TypeTagValues +COORDSTEX Reveal.hpp /^ OUTPUTTEX, SLICETEX, SELECTTEX, INSIDETEX, SURFACETEX, COORDSTEX,$/;" e enum:Reveal::REVIL_UNIFORM +CamGeometry geoms/CamGeometry.cpp /^CamGeometry::CamGeometry(const int& width, const int& height): Geometry() {$/;" f class:CamGeometry +CamGeometry geoms/CamGeometry.hpp /^ CamGeometry(const int& width, const int& height);$/;" p class:CamGeometry +CamGeometry geoms/CamGeometry.hpp /^class CamGeometry : public Geometry {$/;" c +CamGeometry_h geoms/CamGeometry.hpp 25;" d +Capacity osc/oscPack/osc/OscOutboundPacketStream.cpp /^std::size_t OutboundPacketStream::Capacity() const$/;" f class:osc::OutboundPacketStream +Capacity osc/oscPack/osc/OscOutboundPacketStream.h /^ std::size_t Capacity() const;$/;" p class:osc::OutboundPacketStream +CheckForAvailableArgumentSpace osc/oscPack/osc/OscOutboundPacketStream.cpp /^void OutboundPacketStream::CheckForAvailableArgumentSpace( std::size_t argumentLength )$/;" f class:osc::OutboundPacketStream +CheckForAvailableArgumentSpace osc/oscPack/osc/OscOutboundPacketStream.h /^ void CheckForAvailableArgumentSpace( std::size_t argumentLength );$/;" p class:osc::OutboundPacketStream +CheckForAvailableBundleSpace osc/oscPack/osc/OscOutboundPacketStream.cpp /^void OutboundPacketStream::CheckForAvailableBundleSpace()$/;" f class:osc::OutboundPacketStream +CheckForAvailableBundleSpace osc/oscPack/osc/OscOutboundPacketStream.h /^ void CheckForAvailableBundleSpace();$/;" p class:osc::OutboundPacketStream +CheckForAvailableMessageSpace osc/oscPack/osc/OscOutboundPacketStream.cpp /^void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )$/;" f class:osc::OutboundPacketStream +CheckForAvailableMessageSpace osc/oscPack/osc/OscOutboundPacketStream.h /^ void CheckForAvailableMessageSpace( const char *addressPattern );$/;" p class:osc::OutboundPacketStream +Clear osc/oscPack/osc/OscOutboundPacketStream.cpp /^void OutboundPacketStream::Clear()$/;" f class:osc::OutboundPacketStream +Clear osc/oscPack/osc/OscOutboundPacketStream.h /^ void Clear();$/;" p class:osc::OutboundPacketStream +CompareScheduledTimerCalls osc/oscPack/ip/posix/UdpSocket.cpp /^static bool CompareScheduledTimerCalls( $/;" f file: +CompareScheduledTimerCalls osc/oscPack/ip/win32/UdpSocket.cpp /^static bool CompareScheduledTimerCalls( $/;" f file: +ComputeArrayItemCount osc/oscPack/osc/OscReceivedElements.cpp /^std::size_t ReceivedMessageArgument::ComputeArrayItemCount() const$/;" f class:osc::ReceivedMessageArgument +ComputeArrayItemCount osc/oscPack/osc/OscReceivedElements.h /^ std::size_t ComputeArrayItemCount() const;$/;" p class:osc::ReceivedMessageArgument +ConeGeometry geoms/ConeGeometry.cpp /^ConeGeometry::ConeGeometry(): Geometry() {$/;" f class:ConeGeometry +ConeGeometry geoms/ConeGeometry.hpp /^ ConeGeometry();$/;" p class:ConeGeometry +ConeGeometry geoms/ConeGeometry.hpp /^class ConeGeometry : public Geometry {$/;" c +ConeGeometry_h geoms/ConeGeometry.hpp 25;" d +Connect osc/oscPack/ip/UdpSocket.h /^ void Connect( const IpEndpointName& remoteEndpoint ); $/;" p class:UdpSocket +Connect osc/oscPack/ip/posix/UdpSocket.cpp /^ void Connect( const IpEndpointName& remoteEndpoint )$/;" f class:UdpSocket::Implementation +Connect osc/oscPack/ip/posix/UdpSocket.cpp /^void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )$/;" f class:UdpSocket +Connect osc/oscPack/ip/win32/UdpSocket.cpp /^ void Connect( const IpEndpointName& remoteEndpoint )$/;" f class:UdpSocket::Implementation +Connect osc/oscPack/ip/win32/UdpSocket.cpp /^void UdpSocket::Connect( const IpEndpointName& remoteEndpoint )$/;" f class:UdpSocket +Contents osc/oscPack/osc/OscReceivedElements.h /^ const char *Contents() const { return contents_; }$/;" f class:osc::ReceivedPacket +Contents osc/oscPack/osc/OscReceivedElements.h /^ const char *Contents() const { return sizePtr_ + osc::OSC_SIZEOF_INT32; }$/;" f class:osc::ReceivedBundleElement +ContextGeometry geoms/Geometry.hpp /^struct ContextGeometry {$/;" s +ContextHandler modules/ContextHandler.hpp /^class ContextHandler {$/;" c +ContextHandler_h modules/ContextHandler.hpp 25;" d +CutWindow modules/RevealedCutModule.cpp /^CutWindow::CutWindow(CutWindowsManager* man, $/;" f class:CutWindow +CutWindow modules/RevealedCutModule.hpp /^ CutWindow(CutWindowsManager* man, Display* disp, const Window& win);$/;" p class:CutWindow +CutWindow modules/RevealedCutModule.hpp /^class CutWindow {$/;" c +CutWindowsManager modules/RevealedCutModule.cpp /^CutWindowsManager::CutWindowsManager() {$/;" f class:CutWindowsManager +CutWindowsManager modules/RevealedCutModule.hpp /^ CutWindowsManager();$/;" p class:CutWindowsManager +CutWindowsManager modules/RevealedCutModule.hpp /^class CutWindowsManager {$/;" c +DEPTHID Reveal.hpp /^ DEPTHTYPE, DEPTHID, OUTPUTCURS, $/;" e enum:Reveal::REVIL_UNIFORM +DEPTHTYPE Reveal.hpp /^ DEPTHTYPE, DEPTHID, OUTPUTCURS, $/;" e enum:Reveal::REVIL_UNIFORM +DOUBLE_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ DOUBLE_TYPE_TAG = 'd',$/;" e enum:osc::TypeTagValues +Data osc/oscPack/osc/OscOutboundPacketStream.cpp /^const char *OutboundPacketStream::Data() const$/;" f class:osc::OutboundPacketStream +Data osc/oscPack/osc/OscOutboundPacketStream.h /^ const char *Data() const;$/;" p class:osc::OutboundPacketStream +DepthCamModule modules/DepthCamModule.cpp /^DepthCamModule::DepthCamModule(): GroupModule(),$/;" f class:DepthCamModule +DepthCamModule modules/DepthCamModule.hpp /^ DepthCamModule();$/;" p class:DepthCamModule +DepthCamModule modules/DepthCamModule.hpp /^class DepthCamModule : public GroupModule, public DepthModule {$/;" c +DepthCamModule_h modules/DepthCamModule.hpp 25;" d +DepthGroupModule modules/DepthGroupModule.cpp /^DepthGroupModule::DepthGroupModule(): GroupModule(), DepthModule() {$/;" f class:DepthGroupModule +DepthGroupModule modules/DepthGroupModule.hpp /^ DepthGroupModule();$/;" p class:DepthGroupModule +DepthGroupModule modules/DepthGroupModule.hpp /^class DepthGroupModule : public GroupModule, public DepthModule {$/;" c +DepthGroupModule_h modules/DepthGroupModule.hpp 25;" d +DepthMeshModule modules/DepthMeshModule.cpp /^DepthMeshModule::DepthMeshModule(): DepthModule() {$/;" f class:DepthMeshModule +DepthMeshModule modules/DepthMeshModule.hpp /^ DepthMeshModule();$/;" p class:DepthMeshModule +DepthMeshModule modules/DepthMeshModule.hpp /^class DepthMeshModule : public DepthModule {$/;" c +DepthMeshModule_h modules/DepthMeshModule.hpp 25;" d +DepthModule modules/DepthModule.cpp /^DepthModule::DepthModule(): GeomModule(), m_space(NULL) {}$/;" f class:DepthModule +DepthModule modules/DepthModule.hpp /^ DepthModule();$/;" p class:DepthModule +DepthModule modules/DepthModule.hpp /^class DepthModule : public virtual GeomModule {$/;" c +DepthModule_h modules/DepthModule.hpp 25;" d +DepthShapeModule modules/DepthShapeModule.cpp /^DepthShapeModule::DepthShapeModule(): ShapeModule(), DepthModule() {$/;" f class:DepthShapeModule +DepthShapeModule modules/DepthShapeModule.hpp /^ DepthShapeModule();$/;" p class:DepthShapeModule +DepthShapeModule modules/DepthShapeModule.hpp /^class DepthShapeModule : public ShapeModule, public DepthModule {$/;" c +DepthShapeModule_h modules/DepthShapeModule.hpp 25;" d +DetachPeriodicTimerListener osc/oscPack/ip/UdpSocket.h /^ void DetachPeriodicTimerListener( TimerListener *listener ); $/;" p class:SocketReceiveMultiplexer +DetachPeriodicTimerListener osc/oscPack/ip/posix/UdpSocket.cpp /^ void DetachPeriodicTimerListener( TimerListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +DetachPeriodicTimerListener osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener )$/;" f class:SocketReceiveMultiplexer +DetachPeriodicTimerListener osc/oscPack/ip/win32/UdpSocket.cpp /^ void DetachPeriodicTimerListener( TimerListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +DetachPeriodicTimerListener osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::DetachPeriodicTimerListener( TimerListener *listener )$/;" f class:SocketReceiveMultiplexer +DetachSocketListener osc/oscPack/ip/UdpSocket.h /^ void DetachSocketListener( UdpSocket *socket, PacketListener *listener );$/;" p class:SocketReceiveMultiplexer +DetachSocketListener osc/oscPack/ip/posix/UdpSocket.cpp /^ void DetachSocketListener( UdpSocket *socket, PacketListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +DetachSocketListener osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener )$/;" f class:SocketReceiveMultiplexer +DetachSocketListener osc/oscPack/ip/win32/UdpSocket.cpp /^ void DetachSocketListener( UdpSocket *socket, PacketListener *listener )$/;" f class:SocketReceiveMultiplexer::Implementation +DetachSocketListener osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::DetachSocketListener( UdpSocket *socket, PacketListener *listener )$/;" f class:SocketReceiveMultiplexer +EPSILON modules/RevealedModelModule.cpp 29;" d file: +ElementCount osc/oscPack/osc/OscReceivedElements.h /^ uint32 ElementCount() const { return elementCount_; }$/;" f class:osc::ReceivedBundle +ElementSizeSlotRequired osc/oscPack/osc/OscOutboundPacketStream.cpp /^bool OutboundPacketStream::ElementSizeSlotRequired() const$/;" f class:osc::OutboundPacketStream +ElementSizeSlotRequired osc/oscPack/osc/OscOutboundPacketStream.h /^ bool ElementSizeSlotRequired() const;$/;" p class:osc::OutboundPacketStream +ElementsBegin osc/oscPack/osc/OscReceivedElements.h /^ ReceivedBundleElementIterator ElementsBegin() const$/;" f class:osc::ReceivedBundle +ElementsEnd osc/oscPack/osc/OscReceivedElements.h /^ ReceivedBundleElementIterator ElementsEnd() const$/;" f class:osc::ReceivedBundle +EndArray osc/oscPack/osc/OscTypes.cpp /^ArrayTerminator EndArray;$/;" m namespace:osc file: +EndBundle osc/oscPack/osc/OscTypes.cpp /^BundleTerminator EndBundle;$/;" m namespace:osc file: +EndElement osc/oscPack/osc/OscOutboundPacketStream.cpp /^void OutboundPacketStream::EndElement( char *endPtr )$/;" f class:osc::OutboundPacketStream +EndElement osc/oscPack/osc/OscOutboundPacketStream.h /^ void EndElement( char *endPtr );$/;" p class:osc::OutboundPacketStream +EndMessage osc/oscPack/osc/OscTypes.cpp /^MessageTerminator EndMessage;$/;" m namespace:osc file: +Eos osc/oscPack/osc/OscReceivedElements.h /^ bool Eos() const { return p_ == end_; }$/;" f class:osc::ReceivedMessageArgumentStream +Exception osc/oscPack/osc/OscException.h /^ Exception( const Exception& src ) throw()$/;" f class:osc::Exception +Exception osc/oscPack/osc/OscException.h /^ Exception( const char *w ) throw()$/;" f class:osc::Exception +Exception osc/oscPack/osc/OscException.h /^ Exception() throw() {}$/;" f class:osc::Exception +Exception osc/oscPack/osc/OscException.h /^class Exception : public std::exception {$/;" c namespace:osc +ExcessArgumentException osc/oscPack/osc/OscReceivedElements.h /^ ExcessArgumentException( const char *w="too many arguments" )$/;" f class:osc::ExcessArgumentException +ExcessArgumentException osc/oscPack/osc/OscReceivedElements.h /^class ExcessArgumentException : public Exception{$/;" c namespace:osc +FALSE_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ FALSE_TYPE_TAG = 'F',$/;" e enum:osc::TypeTagValues +FILE_OPEN_ATTRIBUTE modules/Attribute.hpp /^ FILE_OPEN_ATTRIBUTE, $/;" e enum:Attribute::TYPE +FILE_SAVE_ATTRIBUTE modules/Attribute.hpp /^ FILE_SAVE_ATTRIBUTE, $/;" e enum:Attribute::TYPE +FLOAT_ATTRIBUTE modules/Attribute.hpp /^ enum TYPE {FLOAT_ATTRIBUTE, $/;" e enum:Attribute::TYPE +FLOAT_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ FLOAT_TYPE_TAG = 'f',$/;" e enum:osc::TypeTagValues +FOLDER_OPEN_ATTRIBUTE modules/Attribute.hpp /^ FOLDER_OPEN_ATTRIBUTE, $/;" e enum:Attribute::TYPE +FileCallback modules/Attribute.hpp /^ typedef void (FileCallback) (Module*, const std::string&);$/;" t class:Attribute +FindStr4End osc/oscPack/osc/OscReceivedElements.cpp /^static inline const char* FindStr4End( const char *p )$/;" f namespace:osc +FindStr4End osc/oscPack/osc/OscReceivedElements.cpp /^static inline const char* FindStr4End( const char *p, const char *end )$/;" f namespace:osc +FloatCallback modules/Attribute.hpp /^ typedef void (FloatCallback) (Module*, const std::vector<float>&);$/;" t class:Attribute +FromInt32 osc/oscPack/osc/OscOutboundPacketStream.cpp /^static void FromInt32( char *p, int32 x )$/;" f namespace:osc +FromInt64 osc/oscPack/osc/OscOutboundPacketStream.cpp /^static void FromInt64( char *p, int64 x )$/;" f namespace:osc +FromUInt32 osc/oscPack/osc/OscOutboundPacketStream.cpp /^static void FromUInt32( char *p, uint32 x )$/;" f namespace:osc +FromUInt64 osc/oscPack/osc/OscOutboundPacketStream.cpp /^static void FromUInt64( char *p, uint64 x )$/;" f namespace:osc +GEOM_BOX Reveal.hpp /^ GEOM_BOX, GEOM_QUAD, GEOM_SPHERE, GEOM_TUBE, GEOM_CONE,$/;" e enum:Reveal::GEOM_ID +GEOM_CAM1280 Reveal.hpp /^ GEOM_CAM1280, GEOM_CAM640, GEOM_CAM320,$/;" e enum:Reveal::GEOM_ID +GEOM_CAM320 Reveal.hpp /^ GEOM_CAM1280, GEOM_CAM640, GEOM_CAM320,$/;" e enum:Reveal::GEOM_ID +GEOM_CAM640 Reveal.hpp /^ GEOM_CAM1280, GEOM_CAM640, GEOM_CAM320,$/;" e enum:Reveal::GEOM_ID +GEOM_CONE Reveal.hpp /^ GEOM_BOX, GEOM_QUAD, GEOM_SPHERE, GEOM_TUBE, GEOM_CONE,$/;" e enum:Reveal::GEOM_ID +GEOM_CUSTOM Reveal.hpp /^ GEOM_PATH, GEOM_CUSTOM$/;" e enum:Reveal::GEOM_ID +GEOM_ID Reveal.hpp /^ enum GEOM_ID { $/;" g class:Reveal +GEOM_PATH Reveal.hpp /^ GEOM_PATH, GEOM_CUSTOM$/;" e enum:Reveal::GEOM_ID +GEOM_QUAD Reveal.hpp /^ GEOM_BOX, GEOM_QUAD, GEOM_SPHERE, GEOM_TUBE, GEOM_CONE,$/;" e enum:Reveal::GEOM_ID +GEOM_SPHERE Reveal.hpp /^ GEOM_BOX, GEOM_QUAD, GEOM_SPHERE, GEOM_TUBE, GEOM_CONE,$/;" e enum:Reveal::GEOM_ID +GEOM_TUBE Reveal.hpp /^ GEOM_BOX, GEOM_QUAD, GEOM_SPHERE, GEOM_TUBE, GEOM_CONE,$/;" e enum:Reveal::GEOM_ID +GLM_ENABLE_EXPERIMENTAL modules/Module.hpp 29;" d +GLOBAL modules/Attribute.hpp /^ enum ACCESSIBILITY {HIDDEN, OUTPUT, LOCAL, GLOBAL};$/;" e enum:Attribute::ACCESSIBILITY +GRADIENTTYPE Reveal.hpp /^ INSIDE, SURFACE, GRADIENTTYPE, SURFACETHICKNESS,$/;" e enum:Reveal::REVIL_UNIFORM +GeomModule modules/GeomModule.cpp /^GeomModule::GeomModule(): Module(), $/;" f class:GeomModule +GeomModule modules/GeomModule.hpp /^ GeomModule();$/;" p class:GeomModule +GeomModule modules/GeomModule.hpp /^class GeomModule : public virtual Module {$/;" c +GeomModule_h modules/GeomModule.hpp 25;" d +Geometry geoms/Geometry.cpp /^Geometry::Geometry():m_hasTexCoords(false), m_points(false) {}$/;" f class:Geometry +Geometry geoms/Geometry.hpp /^ Geometry();$/;" p class:Geometry +Geometry geoms/Geometry.hpp /^class Geometry {$/;" c +Geometry_h geoms/Geometry.hpp 25;" d +GetCurrentTimeMs osc/oscPack/ip/posix/UdpSocket.cpp /^ double GetCurrentTimeMs() const$/;" f class:SocketReceiveMultiplexer::Implementation file: +GetCurrentTimeMs osc/oscPack/ip/win32/UdpSocket.cpp /^ double GetCurrentTimeMs() const$/;" f class:SocketReceiveMultiplexer::Implementation file: +GetHostByName osc/oscPack/ip/IpEndpointName.cpp /^unsigned long IpEndpointName::GetHostByName( const char *s )$/;" f class:IpEndpointName +GetHostByName osc/oscPack/ip/IpEndpointName.h /^ static unsigned long GetHostByName( const char *s );$/;" p class:IpEndpointName +GetHostByName osc/oscPack/ip/NetworkingUtils.h /^unsigned long GetHostByName( const char *name );$/;" p +GetHostByName osc/oscPack/ip/posix/NetworkingUtils.cpp /^unsigned long GetHostByName( const char *name )$/;" f +GetHostByName osc/oscPack/ip/win32/NetworkingUtils.cpp /^unsigned long GetHostByName( const char *name )$/;" f +GroupModule modules/GroupModule.cpp /^GroupModule::GroupModule():Module() {$/;" f class:GroupModule +GroupModule modules/GroupModule.hpp /^ GroupModule();$/;" p class:GroupModule +GroupModule modules/GroupModule.hpp /^class GroupModule: public virtual Module {$/;" c +GroupModule_h modules/GroupModule.hpp 25;" d +GuiListener gui/GuiListener.cpp /^GuiListener::GuiListener(AttributeWidget* wid):Listener(), $/;" f class:GuiListener +GuiListener gui/GuiListener.hpp /^ GuiListener(AttributeWidget*);$/;" p class:GuiListener +GuiListener gui/GuiListener.hpp /^class GuiListener: public Listener {$/;" c +GuiListener_h gui/GuiListener.hpp 25;" d +HIDDEN modules/Attribute.hpp /^ enum ACCESSIBILITY {HIDDEN, OUTPUT, LOCAL, GLOBAL};$/;" e enum:Attribute::ACCESSIBILITY +INCLUDED_OSCPACK_IPENDPOINTNAME_H osc/oscPack/ip/IpEndpointName.h 38;" d +INCLUDED_OSCPACK_MESSAGEMAPPINGOSCPACKETLISTENER_H osc/oscPack/osc/MessageMappingOscPacketListener.h 38;" d +INCLUDED_OSCPACK_NETWORKINGUTILS_H osc/oscPack/ip/NetworkingUtils.h 38;" d +INCLUDED_OSCPACK_OSCEXCEPTION_H osc/oscPack/osc/OscException.h 38;" d +INCLUDED_OSCPACK_OSCHOSTENDIANNESS_H osc/oscPack/osc/OscHostEndianness.h 38;" d +INCLUDED_OSCPACK_OSCOUTBOUNDPACKETSTREAM_H osc/oscPack/osc/OscOutboundPacketStream.h 38;" d +INCLUDED_OSCPACK_OSCPACKETLISTENER_H osc/oscPack/osc/OscPacketListener.h 38;" d +INCLUDED_OSCPACK_OSCPRINTRECEIVEDELEMENTS_H osc/oscPack/osc/OscPrintReceivedElements.h 38;" d +INCLUDED_OSCPACK_OSCRECEIVEDELEMENTS_H osc/oscPack/osc/OscReceivedElements.h 38;" d +INCLUDED_OSCPACK_OSCTYPES_H osc/oscPack/osc/OscTypes.h 38;" d +INCLUDED_OSCPACK_PACKETLISTENER_H osc/oscPack/ip/PacketListener.h 38;" d +INCLUDED_OSCPACK_TIMERLISTENER_H osc/oscPack/ip/TimerListener.h 38;" d +INCLUDED_OSCPACK_UDPSOCKET_H osc/oscPack/ip/UdpSocket.h 38;" d +INFINITUM_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ INFINITUM_TYPE_TAG = 'I',$/;" e enum:osc::TypeTagValues +INSIDE Reveal.hpp /^ INSIDE, SURFACE, GRADIENTTYPE, SURFACETHICKNESS,$/;" e enum:Reveal::REVIL_UNIFORM +INSIDETEX Reveal.hpp /^ OUTPUTTEX, SLICETEX, SELECTTEX, INSIDETEX, SURFACETEX, COORDSTEX,$/;" e enum:Reveal::REVIL_UNIFORM +INT32_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ INT32_TYPE_TAG = 'i',$/;" e enum:osc::TypeTagValues +INT64_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ INT64_TYPE_TAG = 'h',$/;" e enum:osc::TypeTagValues +INT_ATTRIBUTE modules/Attribute.hpp /^ INT_ATTRIBUTE, $/;" e enum:Attribute::TYPE +IP_MTU_SIZE osc/OscManager.hpp 37;" d +ImageTracker modules/DepthCamModule.cpp /^ImageTracker::ImageTracker():Tracker() {$/;" f class:ImageTracker +ImageTracker modules/DepthCamModule.hpp /^ ImageTracker();$/;" p class:ImageTracker +ImageTracker modules/DepthCamModule.hpp /^class ImageTracker : public Tracker {$/;" c +Implementation osc/oscPack/ip/posix/UdpSocket.cpp /^ Implementation()$/;" f class:UdpSocket::Implementation +Implementation osc/oscPack/ip/posix/UdpSocket.cpp /^ Implementation()$/;" f class:SocketReceiveMultiplexer::Implementation +Implementation osc/oscPack/ip/posix/UdpSocket.cpp /^class SocketReceiveMultiplexer::Implementation{$/;" c class:SocketReceiveMultiplexer file: +Implementation osc/oscPack/ip/posix/UdpSocket.cpp /^class UdpSocket::Implementation{$/;" c class:UdpSocket file: +Implementation osc/oscPack/ip/win32/UdpSocket.cpp /^ Implementation()$/;" f class:UdpSocket::Implementation +Implementation osc/oscPack/ip/win32/UdpSocket.cpp /^ Implementation()$/;" f class:SocketReceiveMultiplexer::Implementation +Implementation osc/oscPack/ip/win32/UdpSocket.cpp /^class SocketReceiveMultiplexer::Implementation{$/;" c class:SocketReceiveMultiplexer file: +Implementation osc/oscPack/ip/win32/UdpSocket.cpp /^class UdpSocket::Implementation{$/;" c class:UdpSocket file: +Infinitum osc/oscPack/osc/OscTypes.cpp /^InfinitumType Infinitum;$/;" m namespace:osc file: +InfinitumType osc/oscPack/osc/OscTypes.h /^struct InfinitumType{$/;" s namespace:osc +Init osc/oscPack/osc/OscReceivedElements.cpp /^void ReceivedBundle::Init( const char *bundle, osc_bundle_element_size_t size )$/;" f class:osc::ReceivedBundle +Init osc/oscPack/osc/OscReceivedElements.cpp /^void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size )$/;" f class:osc::ReceivedMessage +Init osc/oscPack/osc/OscReceivedElements.h /^ void Init( const char *bundle, osc_bundle_element_size_t size );$/;" p class:osc::ReceivedMessage +Init osc/oscPack/osc/OscReceivedElements.h /^ void Init( const char *message, osc_bundle_element_size_t size );$/;" p class:osc::ReceivedBundle +IntCallback modules/Attribute.hpp /^ typedef void (IntCallback) (Module*, const std::vector<int>&);$/;" t class:Attribute +InterruptSignalHandler osc/oscPack/ip/posix/UdpSocket.cpp /^\/*static*\/ void InterruptSignalHandler( int )$/;" f +InterruptSignalHandler osc/oscPack/ip/posix/UdpSocket.cpp /^extern "C" \/*static*\/ void InterruptSignalHandler( int );$/;" p file: +InterruptSignalHandler osc/oscPack/ip/win32/UdpSocket.cpp /^\/*static*\/ void InterruptSignalHandler( int )$/;" f +InterruptSignalHandler osc/oscPack/ip/win32/UdpSocket.cpp /^extern "C" \/*static*\/ void InterruptSignalHandler( int );$/;" p file: +IpEndpointName osc/oscPack/ip/IpEndpointName.h /^ IpEndpointName( const char *addressName, int port_=ANY_PORT )$/;" f class:IpEndpointName +IpEndpointName osc/oscPack/ip/IpEndpointName.h /^ IpEndpointName( int addressA, int addressB, int addressC, int addressD, int port_=ANY_PORT )$/;" f class:IpEndpointName +IpEndpointName osc/oscPack/ip/IpEndpointName.h /^ IpEndpointName( int port_ ) $/;" f class:IpEndpointName +IpEndpointName osc/oscPack/ip/IpEndpointName.h /^ IpEndpointName( unsigned long ipAddress_, int port_ ) $/;" f class:IpEndpointName +IpEndpointName osc/oscPack/ip/IpEndpointName.h /^ IpEndpointName()$/;" f class:IpEndpointName +IpEndpointName osc/oscPack/ip/IpEndpointName.h /^class IpEndpointName{$/;" c +IpEndpointNameFromSockaddr osc/oscPack/ip/posix/UdpSocket.cpp /^static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr )$/;" f file: +IpEndpointNameFromSockaddr osc/oscPack/ip/win32/UdpSocket.cpp /^static IpEndpointName IpEndpointNameFromSockaddr( const struct sockaddr_in& sockAddr )$/;" f file: +IsArrayBegin osc/oscPack/osc/OscReceivedElements.h /^ bool IsArrayBegin() const { return *typeTagPtr_ == ARRAY_BEGIN_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsArrayEnd osc/oscPack/osc/OscReceivedElements.h /^ bool IsArrayEnd() const { return *typeTagPtr_ == ARRAY_END_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsBlob osc/oscPack/osc/OscReceivedElements.h /^ bool IsBlob() const { return *typeTagPtr_ == BLOB_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsBool osc/oscPack/osc/OscReceivedElements.h /^ bool IsBool() const$/;" f class:osc::ReceivedMessageArgument +IsBound osc/oscPack/ip/UdpSocket.h /^ bool IsBound() const;$/;" p class:UdpSocket +IsBound osc/oscPack/ip/posix/UdpSocket.cpp /^ bool IsBound() const { return isBound_; }$/;" f class:UdpSocket::Implementation +IsBound osc/oscPack/ip/posix/UdpSocket.cpp /^bool UdpSocket::IsBound() const$/;" f class:UdpSocket +IsBound osc/oscPack/ip/win32/UdpSocket.cpp /^ bool IsBound() const { return isBound_; }$/;" f class:UdpSocket::Implementation +IsBound osc/oscPack/ip/win32/UdpSocket.cpp /^bool UdpSocket::IsBound() const$/;" f class:UdpSocket +IsBundle osc/oscPack/osc/OscReceivedElements.cpp /^bool ReceivedBundleElement::IsBundle() const$/;" f class:osc::ReceivedBundleElement +IsBundle osc/oscPack/osc/OscReceivedElements.cpp /^bool ReceivedPacket::IsBundle() const$/;" f class:osc::ReceivedPacket +IsBundle osc/oscPack/osc/OscReceivedElements.h /^ bool IsBundle() const;$/;" p class:osc::ReceivedBundleElement +IsBundle osc/oscPack/osc/OscReceivedElements.h /^ bool IsBundle() const;$/;" p class:osc::ReceivedPacket +IsBundleInProgress osc/oscPack/osc/OscOutboundPacketStream.cpp /^bool OutboundPacketStream::IsBundleInProgress() const$/;" f class:osc::OutboundPacketStream +IsBundleInProgress osc/oscPack/osc/OscOutboundPacketStream.h /^ bool IsBundleInProgress() const;$/;" p class:osc::OutboundPacketStream +IsChar osc/oscPack/osc/OscReceivedElements.h /^ bool IsChar() const { return *typeTagPtr_ == CHAR_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsDouble osc/oscPack/osc/OscReceivedElements.h /^ bool IsDouble() const { return *typeTagPtr_ == DOUBLE_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsEqualTo osc/oscPack/osc/OscReceivedElements.h /^ bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const$/;" f class:osc::ReceivedBundleElementIterator +IsEqualTo osc/oscPack/osc/OscReceivedElements.h /^ bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const$/;" f class:osc::ReceivedMessageArgumentIterator +IsFloat osc/oscPack/osc/OscReceivedElements.h /^ bool IsFloat() const { return *typeTagPtr_ == FLOAT_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsInfinitum osc/oscPack/osc/OscReceivedElements.h /^ bool IsInfinitum() const { return *typeTagPtr_ == INFINITUM_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsInt32 osc/oscPack/osc/OscReceivedElements.h /^ bool IsInt32() const { return *typeTagPtr_ == INT32_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsInt64 osc/oscPack/osc/OscReceivedElements.h /^ bool IsInt64() const { return *typeTagPtr_ == INT64_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsMessage osc/oscPack/osc/OscReceivedElements.h /^ bool IsMessage() const { return !IsBundle(); }$/;" f class:osc::ReceivedBundleElement +IsMessage osc/oscPack/osc/OscReceivedElements.h /^ bool IsMessage() const { return !IsBundle(); }$/;" f class:osc::ReceivedPacket +IsMessageInProgress osc/oscPack/osc/OscOutboundPacketStream.cpp /^bool OutboundPacketStream::IsMessageInProgress() const$/;" f class:osc::OutboundPacketStream +IsMessageInProgress osc/oscPack/osc/OscOutboundPacketStream.h /^ bool IsMessageInProgress() const;$/;" p class:osc::OutboundPacketStream +IsMidiMessage osc/oscPack/osc/OscReceivedElements.h /^ bool IsMidiMessage() const { return *typeTagPtr_ == MIDI_MESSAGE_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsMulticastAddress osc/oscPack/ip/IpEndpointName.h /^ bool IsMulticastAddress() const { return ((address >> 24) & 0xFF) >= 224 && ((address >> 24) & 0xFF) <= 239; }$/;" f class:IpEndpointName +IsMultipleOf4 osc/oscPack/osc/OscTypes.h /^inline bool IsMultipleOf4( osc_bundle_element_size_t x )$/;" f namespace:osc +IsNil osc/oscPack/osc/OscReceivedElements.h /^ bool IsNil() const { return *typeTagPtr_ == NIL_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsReady osc/oscPack/osc/OscOutboundPacketStream.cpp /^bool OutboundPacketStream::IsReady() const$/;" f class:osc::OutboundPacketStream +IsReady osc/oscPack/osc/OscOutboundPacketStream.h /^ bool IsReady() const;$/;" p class:osc::OutboundPacketStream +IsRgbaColor osc/oscPack/osc/OscReceivedElements.h /^ bool IsRgbaColor() const { return *typeTagPtr_ == RGBA_COLOR_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsString osc/oscPack/osc/OscReceivedElements.h /^ bool IsString() const { return *typeTagPtr_ == STRING_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsSymbol osc/oscPack/osc/OscReceivedElements.h /^ bool IsSymbol() const { return *typeTagPtr_ == SYMBOL_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsTimeTag osc/oscPack/osc/OscReceivedElements.h /^ bool IsTimeTag() const { return *typeTagPtr_ == TIME_TAG_TYPE_TAG; }$/;" f class:osc::ReceivedMessageArgument +IsValidElementSizeValue osc/oscPack/osc/OscTypes.h /^inline bool IsValidElementSizeValue( osc_bundle_element_size_t x )$/;" f namespace:osc +LOCAL modules/Attribute.hpp /^ enum ACCESSIBILITY {HIDDEN, OUTPUT, LOCAL, GLOBAL};$/;" e enum:Attribute::ACCESSIBILITY +Listener modules/Listener.cpp /^Listener::Listener(){}$/;" f class:Listener +Listener modules/Listener.hpp /^ Listener();$/;" p class:Listener +Listener modules/Listener.hpp /^class Listener {$/;" c +ListenerWidget gui/ListenerWidget.cpp /^ListenerWidget::ListenerWidget(int x, int y, $/;" f class:ListenerWidget +ListenerWidget gui/ListenerWidget.hpp /^ ListenerWidget(int x, int y, int w, int h, Listener* listener);$/;" p class:ListenerWidget +ListenerWidget gui/ListenerWidget.hpp /^class ListenerWidget : public Fl_Group {$/;" c +ListenerWidget_h gui/ListenerWidget.hpp 24;" d +Listener_h modules/Listener.hpp 25;" d +LocalEndpointFor osc/oscPack/ip/UdpSocket.h /^ IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const;$/;" p class:UdpSocket +LocalEndpointFor osc/oscPack/ip/posix/UdpSocket.cpp /^ IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const$/;" f class:UdpSocket::Implementation +LocalEndpointFor osc/oscPack/ip/posix/UdpSocket.cpp /^IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const$/;" f class:UdpSocket +LocalEndpointFor osc/oscPack/ip/win32/UdpSocket.cpp /^ IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const$/;" f class:UdpSocket::Implementation +LocalEndpointFor osc/oscPack/ip/win32/UdpSocket.cpp /^IpEndpointName UdpSocket::LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const$/;" f class:UdpSocket +MARKTEX Reveal.hpp /^ CAMFILTER, CAMCONTOURTHRESH, CAMMARKERS, MARKTEX, BACKGROUND,$/;" e enum:Reveal::REVIL_UNIFORM +MIDI_MESSAGE_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ MIDI_MESSAGE_TYPE_TAG = 'm',$/;" e enum:osc::TypeTagValues +MIRRORED Reveal.hpp /^ VIEWMAT, VIEWPROJMAT, MODELMAT, MIRRORED, $/;" e enum:Reveal::REVIL_UNIFORM +MODELMAT Reveal.hpp /^ VIEWMAT, VIEWPROJMAT, MODELMAT, MIRRORED, $/;" e enum:Reveal::REVIL_UNIFORM +MainWindow gui/MainWindow.cpp /^MainWindow::MainWindow(): Fl_Double_Window(600, 327, "Revil - Configuration"),$/;" f class:MainWindow +MainWindow gui/MainWindow.hpp /^ MainWindow();$/;" p class:MainWindow +MainWindow gui/MainWindow.hpp /^class MainWindow: public Fl_Double_Window {$/;" c +MainWindow_h gui/MainWindow.hpp 25;" d +MalformedBundleException osc/oscPack/osc/OscReceivedElements.h /^ MalformedBundleException( const char *w="malformed bundle" )$/;" f class:osc::MalformedBundleException +MalformedBundleException osc/oscPack/osc/OscReceivedElements.h /^class MalformedBundleException : public Exception{$/;" c namespace:osc +MalformedMessageException osc/oscPack/osc/OscReceivedElements.h /^ MalformedMessageException( const char *w="malformed message" )$/;" f class:osc::MalformedMessageException +MalformedMessageException osc/oscPack/osc/OscReceivedElements.h /^class MalformedMessageException : public Exception{$/;" c namespace:osc +MalformedPacketException osc/oscPack/osc/OscReceivedElements.h /^ MalformedPacketException( const char *w="malformed packet" )$/;" f class:osc::MalformedPacketException +MalformedPacketException osc/oscPack/osc/OscReceivedElements.h /^class MalformedPacketException : public Exception{$/;" c namespace:osc +MessageInProgressException osc/oscPack/osc/OscOutboundPacketStream.h /^ MessageInProgressException($/;" f class:osc::MessageInProgressException +MessageInProgressException osc/oscPack/osc/OscOutboundPacketStream.h /^class MessageInProgressException : public Exception{$/;" c namespace:osc +MessageMappingOscPacketListener osc/oscPack/osc/MessageMappingOscPacketListener.h /^class MessageMappingOscPacketListener : public OscPacketListener{$/;" c namespace:osc +MessageNotInProgressException osc/oscPack/osc/OscOutboundPacketStream.h /^ MessageNotInProgressException($/;" f class:osc::MessageNotInProgressException +MessageNotInProgressException osc/oscPack/osc/OscOutboundPacketStream.h /^class MessageNotInProgressException : public Exception{$/;" c namespace:osc +MessageTerminator osc/oscPack/osc/OscTypes.h /^struct MessageTerminator{$/;" s namespace:osc +MidiMessage osc/oscPack/osc/OscTypes.h /^ MidiMessage() {}$/;" f struct:osc::MidiMessage +MidiMessage osc/oscPack/osc/OscTypes.h /^ explicit MidiMessage( uint32 value_ ) : value( value_ ) {}$/;" f struct:osc::MidiMessage +MidiMessage osc/oscPack/osc/OscTypes.h /^struct MidiMessage{$/;" s namespace:osc +MissingArgumentException osc/oscPack/osc/OscReceivedElements.h /^ MissingArgumentException( const char *w="missing argument" )$/;" f class:osc::MissingArgumentException +MissingArgumentException osc/oscPack/osc/OscReceivedElements.h /^class MissingArgumentException : public Exception{$/;" c namespace:osc +ModelModule modules/ModelModule.cpp /^ModelModule::ModelModule(): GeomModule() {$/;" f class:ModelModule +ModelModule modules/ModelModule.hpp /^ ModelModule();$/;" p class:ModelModule +ModelModule modules/ModelModule.hpp /^class ModelModule : public virtual GeomModule {$/;" c +ModelModule_h modules/ModelModule.hpp 25;" d +ModelVertex modules/ModelModule.hpp /^ struct ModelVertex {$/;" s class:ModelModule +Module modules/Module.cpp /^Module::Module() {$/;" f class:Module +Module modules/Module.hpp /^ Module();$/;" p class:Module +Module modules/Module.hpp /^class Module {$/;" c +ModuleListObserver Reveal.hpp /^class ModuleListObserver {$/;" c +ModuleWidget gui/ModuleWidget.cpp /^ModuleWidget::ModuleWidget(int x, int y, $/;" f class:ModuleWidget +ModuleWidget gui/ModuleWidget.hpp /^ ModuleWidget(int x, int y, int w, int h, Module* module);$/;" p class:ModuleWidget +ModuleWidget gui/ModuleWidget.hpp /^class ModuleWidget : public Fl_Toggle_Button {$/;" c +ModuleWidget_h gui/ModuleWidget.hpp 24;" d +Module_h modules/Module.hpp 25;" d +NIL_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ NIL_TYPE_TAG = 'N',$/;" e enum:osc::TypeTagValues +NetworkInitializer osc/oscPack/ip/NetworkingUtils.h /^ NetworkInitializer();$/;" p class:NetworkInitializer +NetworkInitializer osc/oscPack/ip/NetworkingUtils.h /^class NetworkInitializer{$/;" c +NetworkInitializer osc/oscPack/ip/posix/NetworkingUtils.cpp /^NetworkInitializer::NetworkInitializer() {}$/;" f class:NetworkInitializer +NetworkInitializer osc/oscPack/ip/win32/NetworkingUtils.cpp /^NetworkInitializer::NetworkInitializer()$/;" f class:NetworkInitializer +Nil osc/oscPack/osc/OscTypes.cpp /^NilType Nil; \/\/ Objective-C defines Nil. so our Nil is deprecated. use OscNil instead$/;" m namespace:osc file: +NilType osc/oscPack/osc/OscTypes.h /^struct NilType{$/;" s namespace:osc +OSC_BUNDLE_ELEMENT_SIZE_MAX osc/oscPack/osc/OscTypes.h /^ OSC_BUNDLE_ELEMENT_SIZE_MAX = 0x7FFFFFFC$/;" e enum:osc::__anon5 +OSC_HOST_BIG_ENDIAN osc/oscPack/osc/OscHostEndianness.h 104;" d +OSC_HOST_BIG_ENDIAN osc/oscPack/osc/OscHostEndianness.h 113;" d +OSC_HOST_BIG_ENDIAN osc/oscPack/osc/OscHostEndianness.h 60;" d +OSC_HOST_BIG_ENDIAN osc/oscPack/osc/OscHostEndianness.h 67;" d +OSC_HOST_BIG_ENDIAN osc/oscPack/osc/OscHostEndianness.h 71;" d +OSC_HOST_BIG_ENDIAN osc/oscPack/osc/OscHostEndianness.h 83;" d +OSC_HOST_BIG_ENDIAN osc/oscPack/osc/OscHostEndianness.h 87;" d +OSC_HOST_LITTLE_ENDIAN osc/oscPack/osc/OscHostEndianness.h 103;" d +OSC_HOST_LITTLE_ENDIAN osc/oscPack/osc/OscHostEndianness.h 114;" d +OSC_HOST_LITTLE_ENDIAN osc/oscPack/osc/OscHostEndianness.h 59;" d +OSC_HOST_LITTLE_ENDIAN osc/oscPack/osc/OscHostEndianness.h 66;" d +OSC_HOST_LITTLE_ENDIAN osc/oscPack/osc/OscHostEndianness.h 72;" d +OSC_HOST_LITTLE_ENDIAN osc/oscPack/osc/OscHostEndianness.h 82;" d +OSC_HOST_LITTLE_ENDIAN osc/oscPack/osc/OscHostEndianness.h 88;" d +OSC_INT32_MAX osc/oscPack/osc/OscTypes.h /^ OSC_INT32_MAX = 0x7FFFFFFF,$/;" e enum:osc::__anon5 +OSC_SIZEOF_INT32 osc/oscPack/osc/OscTypes.h /^ OSC_SIZEOF_INT32 = 4,$/;" e enum:osc::ValueTypeSizes +OSC_SIZEOF_INT64 osc/oscPack/osc/OscTypes.h /^ OSC_SIZEOF_INT64 = 8,$/;" e enum:osc::ValueTypeSizes +OSC_SIZEOF_UINT32 osc/oscPack/osc/OscTypes.h /^ OSC_SIZEOF_UINT32 = 4,$/;" e enum:osc::ValueTypeSizes +OSC_SIZEOF_UINT64 osc/oscPack/osc/OscTypes.h /^ OSC_SIZEOF_UINT64 = 8,$/;" e enum:osc::ValueTypeSizes +OUTBLOBSIZE Reveal.hpp /^ OUTSHAPESIZE, OUTBLOBSIZE, OUTDEPTHSIZE, OUTNBDEPTH,$/;" e enum:Reveal::REVIL_UNIFORM +OUTDEPTHSIZE Reveal.hpp /^ OUTSHAPESIZE, OUTBLOBSIZE, OUTDEPTHSIZE, OUTNBDEPTH,$/;" e enum:Reveal::REVIL_UNIFORM +OUTNBDEPTH Reveal.hpp /^ OUTSHAPESIZE, OUTBLOBSIZE, OUTDEPTHSIZE, OUTNBDEPTH,$/;" e enum:Reveal::REVIL_UNIFORM +OUTPUT modules/Attribute.hpp /^ enum ACCESSIBILITY {HIDDEN, OUTPUT, LOCAL, GLOBAL};$/;" e enum:Attribute::ACCESSIBILITY +OUTPUTCURS Reveal.hpp /^ DEPTHTYPE, DEPTHID, OUTPUTCURS, $/;" e enum:Reveal::REVIL_UNIFORM +OUTPUTTEX Reveal.hpp /^ OUTPUTTEX, SLICETEX, SELECTTEX, INSIDETEX, SURFACETEX, COORDSTEX,$/;" e enum:Reveal::REVIL_UNIFORM +OUTSHAPESIZE Reveal.hpp /^ OUTSHAPESIZE, OUTBLOBSIZE, OUTDEPTHSIZE, OUTNBDEPTH,$/;" e enum:Reveal::REVIL_UNIFORM +OscListener osc/OscListener.cpp /^OscListener::OscListener():Listener() {$/;" f class:OscListener +OscListener osc/OscListener.cpp /^OscListener::OscListener(const std::string& adPort):Listener() {$/;" f class:OscListener +OscListener osc/OscListener.hpp /^ OscListener();$/;" p class:OscListener +OscListener osc/OscListener.hpp /^ OscListener(const std::string& adPort);$/;" p class:OscListener +OscListener osc/OscListener.hpp /^class OscListener: public Listener {$/;" c +OscListener_h osc/OscListener.hpp 25;" d +OscManager osc/OscManager.cpp /^OscManager::OscManager(): osc::OscPacketListener() {}$/;" f class:OscManager +OscManager osc/OscManager.hpp /^ OscManager();$/;" p class:OscManager +OscManager osc/OscManager.hpp /^class OscManager : public osc::OscPacketListener {$/;" c +OscManager_h osc/OscManager.hpp 25;" d +OscMessage osc/OscManager.hpp /^struct OscMessage {$/;" s +OscNil osc/oscPack/osc/OscTypes.cpp /^NilType OscNil;$/;" m namespace:osc file: +OscPacketListener osc/oscPack/osc/OscPacketListener.h /^class OscPacketListener : public PacketListener{ $/;" c namespace:osc +OscStream osc/OscManager.hpp /^struct OscStream {$/;" s +OutOfBufferMemoryException osc/oscPack/osc/OscOutboundPacketStream.h /^ OutOfBufferMemoryException( const char *w="out of buffer memory" )$/;" f class:osc::OutOfBufferMemoryException +OutOfBufferMemoryException osc/oscPack/osc/OscOutboundPacketStream.h /^class OutOfBufferMemoryException : public Exception{$/;" c namespace:osc +OutboundPacketStream osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream::OutboundPacketStream( char *buffer, std::size_t capacity )$/;" f class:osc::OutboundPacketStream +OutboundPacketStream osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream( char *buffer, std::size_t capacity );$/;" p class:osc::OutboundPacketStream +OutboundPacketStream osc/oscPack/osc/OscOutboundPacketStream.h /^class OutboundPacketStream{$/;" c namespace:osc +PATBRIGHT Reveal.hpp /^ PATW, PATPOSX, PATPOSY, PATNBX, PATNBY, PATBRIGHT, PATTERNTEX$/;" e enum:Reveal::REVIL_UNIFORM +PATNBX Reveal.hpp /^ PATW, PATPOSX, PATPOSY, PATNBX, PATNBY, PATBRIGHT, PATTERNTEX$/;" e enum:Reveal::REVIL_UNIFORM +PATNBY Reveal.hpp /^ PATW, PATPOSX, PATPOSY, PATNBX, PATNBY, PATBRIGHT, PATTERNTEX$/;" e enum:Reveal::REVIL_UNIFORM +PATPOSX Reveal.hpp /^ PATW, PATPOSX, PATPOSY, PATNBX, PATNBY, PATBRIGHT, PATTERNTEX$/;" e enum:Reveal::REVIL_UNIFORM +PATPOSY Reveal.hpp /^ PATW, PATPOSX, PATPOSY, PATNBX, PATNBY, PATBRIGHT, PATTERNTEX$/;" e enum:Reveal::REVIL_UNIFORM +PATTERNTEX Reveal.hpp /^ PATW, PATPOSX, PATPOSY, PATNBX, PATNBY, PATBRIGHT, PATTERNTEX$/;" e enum:Reveal::REVIL_UNIFORM +PATW Reveal.hpp /^ PATW, PATPOSX, PATPOSY, PATNBX, PATNBY, PATBRIGHT, PATTERNTEX$/;" e enum:Reveal::REVIL_UNIFORM +PREVIEWPROG Reveal.hpp /^ PREVIEWPROG, SLICEPROG, SELECTPROG, RENDERPROG, CALIBPROG$/;" e enum:Reveal::REVIL_PROGRAM +PacketListener osc/oscPack/ip/PacketListener.h /^class PacketListener{$/;" c +PathPoint modules/RevealedPathModule.hpp /^ PathPoint(){}$/;" f class:PathPoint +PathPoint modules/RevealedPathModule.hpp /^ PathPoint(glm::vec4 pnt):m_point(pnt){}$/;" f class:PathPoint +PathPoint modules/RevealedPathModule.hpp /^class PathPoint {$/;" c +PathPointModule modules/RevealedPathModule.cpp /^PathPointModule::PathPointModule(RevealedPathModule* path): $/;" f class:PathPointModule +PathPointModule modules/RevealedPathModule.cpp /^PathPointModule::PathPointModule(RevealedPathModule* path, $/;" f class:PathPointModule +PathPointModule modules/RevealedPathModule.hpp /^ PathPointModule(RevealedPathModule*);$/;" p class:PathPointModule +PathPointModule modules/RevealedPathModule.hpp /^ PathPointModule(RevealedPathModule*, Module*);$/;" p class:PathPointModule +PathPointModule modules/RevealedPathModule.hpp /^class PathPointModule : public PathPoint, public Listener {$/;" c +PreviewModule modules/PreviewModule.cpp /^PreviewModule::PreviewModule():Module() {$/;" f class:PreviewModule +PreviewModule modules/PreviewModule.hpp /^ PreviewModule();$/;" p class:PreviewModule +PreviewModule modules/PreviewModule.hpp /^class PreviewModule: public Module, public ContextHandler {$/;" c +PreviewModule_h modules/PreviewModule.hpp 25;" d +ProcessBundle osc/oscPack/osc/OscPacketListener.h /^ virtual void ProcessBundle( const osc::ReceivedBundle& b, $/;" f class:osc::OscPacketListener +ProcessMessage osc/OscManager.cpp /^void OscManager::ProcessMessage(const osc::ReceivedMessage& mess,$/;" f class:OscManager +ProcessMessage osc/OscManager.hpp /^ virtual void ProcessMessage(const osc::ReceivedMessage& m,$/;" p class:OscManager +ProcessMessage osc/oscPack/osc/MessageMappingOscPacketListener.h /^ virtual void ProcessMessage( const osc::ReceivedMessage& m,$/;" f class:osc::MessageMappingOscPacketListener +ProcessMessage osc/oscPack/osc/OscPacketListener.h /^ virtual void ProcessMessage( const osc::ReceivedMessage& m, $/;" p class:osc::OscPacketListener +ProcessPacket osc/oscPack/ip/PacketListener.h /^ virtual void ProcessPacket( const char *data, int size, $/;" p class:PacketListener +ProcessPacket osc/oscPack/osc/OscPacketListener.h /^ virtual void ProcessPacket( const char *data, int size, $/;" f class:osc::OscPacketListener +ProjectorModule modules/ProjectorModule.cpp /^ProjectorModule::ProjectorModule(): Module() {$/;" f class:ProjectorModule +ProjectorModule modules/ProjectorModule.hpp /^ ProjectorModule();$/;" p class:ProjectorModule +ProjectorModule modules/ProjectorModule.hpp /^class ProjectorModule : public Module, public ContextHandler {$/;" c +ProjectorModule_h modules/ProjectorModule.hpp 25;" d +QuadGeometry geoms/QuadGeometry.cpp /^QuadGeometry::QuadGeometry(): Geometry() {$/;" f class:QuadGeometry +QuadGeometry geoms/QuadGeometry.hpp /^ QuadGeometry();$/;" p class:QuadGeometry +QuadGeometry geoms/QuadGeometry.hpp /^class QuadGeometry : public Geometry {$/;" c +QuadGeometry_h geoms/QuadGeometry.hpp 25;" d +RENDERPROG Reveal.hpp /^ PREVIEWPROG, SLICEPROG, SELECTPROG, RENDERPROG, CALIBPROG$/;" e enum:Reveal::REVIL_PROGRAM +REVBLOB Reveal.hpp /^ REVCURSOR, REVCOLOR, REVBLOB, REVEALEDBY, $/;" e enum:Reveal::REVIL_UNIFORM +REVCENTER Reveal.hpp /^ REVSURFACE, REVINSIDE, REVCENTER, $/;" e enum:Reveal::REVIL_UNIFORM +REVCOLOR Reveal.hpp /^ REVCURSOR, REVCOLOR, REVBLOB, REVEALEDBY, $/;" e enum:Reveal::REVIL_UNIFORM +REVCURSOR Reveal.hpp /^ REVCURSOR, REVCOLOR, REVBLOB, REVEALEDBY, $/;" e enum:Reveal::REVIL_UNIFORM +REVEALEDBY Reveal.hpp /^ REVCURSOR, REVCOLOR, REVBLOB, REVEALEDBY, $/;" e enum:Reveal::REVIL_UNIFORM +REVIL_PROGRAM Reveal.hpp /^ enum REVIL_PROGRAM {$/;" g class:Reveal +REVIL_UNIFORM Reveal.hpp /^ enum REVIL_UNIFORM {$/;" g class:Reveal +REVINSIDE Reveal.hpp /^ REVSURFACE, REVINSIDE, REVCENTER, $/;" e enum:Reveal::REVIL_UNIFORM +REVSURFACE Reveal.hpp /^ REVSURFACE, REVINSIDE, REVCENTER, $/;" e enum:Reveal::REVIL_UNIFORM +RGBA_COLOR_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ RGBA_COLOR_TYPE_TAG = 'r',$/;" e enum:osc::TypeTagValues +ReceiveFrom osc/oscPack/ip/UdpSocket.h /^ std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size );$/;" p class:UdpSocket +ReceiveFrom osc/oscPack/ip/posix/UdpSocket.cpp /^ std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size )$/;" f class:UdpSocket::Implementation +ReceiveFrom osc/oscPack/ip/posix/UdpSocket.cpp /^std::size_t UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size )$/;" f class:UdpSocket +ReceiveFrom osc/oscPack/ip/win32/UdpSocket.cpp /^ std::size_t ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size )$/;" f class:UdpSocket::Implementation +ReceiveFrom osc/oscPack/ip/win32/UdpSocket.cpp /^std::size_t UdpSocket::ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, std::size_t size )$/;" f class:UdpSocket +ReceivedBundle osc/oscPack/osc/OscReceivedElements.cpp /^ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement )$/;" f class:osc::ReceivedBundle +ReceivedBundle osc/oscPack/osc/OscReceivedElements.cpp /^ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet )$/;" f class:osc::ReceivedBundle +ReceivedBundle osc/oscPack/osc/OscReceivedElements.h /^ explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );$/;" p class:osc::ReceivedBundle +ReceivedBundle osc/oscPack/osc/OscReceivedElements.h /^ explicit ReceivedBundle( const ReceivedPacket& packet );$/;" p class:osc::ReceivedBundle +ReceivedBundle osc/oscPack/osc/OscReceivedElements.h /^class ReceivedBundle{$/;" c namespace:osc +ReceivedBundleElement osc/oscPack/osc/OscReceivedElements.h /^ ReceivedBundleElement( const char *sizePtr )$/;" f class:osc::ReceivedBundleElement +ReceivedBundleElement osc/oscPack/osc/OscReceivedElements.h /^class ReceivedBundleElement{$/;" c namespace:osc +ReceivedBundleElementIterator osc/oscPack/osc/OscReceivedElements.h /^ ReceivedBundleElementIterator( const char *sizePtr )$/;" f class:osc::ReceivedBundleElementIterator +ReceivedBundleElementIterator osc/oscPack/osc/OscReceivedElements.h /^class ReceivedBundleElementIterator{$/;" c namespace:osc +ReceivedMessage osc/oscPack/osc/OscReceivedElements.cpp /^ReceivedMessage::ReceivedMessage( const ReceivedBundleElement& bundleElement )$/;" f class:osc::ReceivedMessage +ReceivedMessage osc/oscPack/osc/OscReceivedElements.cpp /^ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet )$/;" f class:osc::ReceivedMessage +ReceivedMessage osc/oscPack/osc/OscReceivedElements.h /^ explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );$/;" p class:osc::ReceivedMessage +ReceivedMessage osc/oscPack/osc/OscReceivedElements.h /^ explicit ReceivedMessage( const ReceivedPacket& packet );$/;" p class:osc::ReceivedMessage +ReceivedMessage osc/oscPack/osc/OscReceivedElements.h /^class ReceivedMessage{$/;" c namespace:osc +ReceivedMessageArgument osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgument( const char *typeTagPtr, const char *argumentPtr )$/;" f class:osc::ReceivedMessageArgument +ReceivedMessageArgument osc/oscPack/osc/OscReceivedElements.h /^class ReceivedMessageArgument{$/;" c namespace:osc +ReceivedMessageArgumentIterator osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )$/;" f class:osc::ReceivedMessageArgumentIterator +ReceivedMessageArgumentIterator osc/oscPack/osc/OscReceivedElements.h /^class ReceivedMessageArgumentIterator{$/;" c namespace:osc +ReceivedMessageArgumentStream osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,$/;" f class:osc::ReceivedMessageArgumentStream +ReceivedMessageArgumentStream osc/oscPack/osc/OscReceivedElements.h /^class ReceivedMessageArgumentStream{$/;" c namespace:osc +ReceivedPacket osc/oscPack/osc/OscReceivedElements.h /^ ReceivedPacket( const char *contents, int size )$/;" f class:osc::ReceivedPacket +ReceivedPacket osc/oscPack/osc/OscReceivedElements.h /^ ReceivedPacket( const char *contents, osc_bundle_element_size_t size )$/;" f class:osc::ReceivedPacket +ReceivedPacket osc/oscPack/osc/OscReceivedElements.h /^ ReceivedPacket( const char *contents, std::size_t size )$/;" f class:osc::ReceivedPacket +ReceivedPacket osc/oscPack/osc/OscReceivedElements.h /^class ReceivedPacket{$/;" c namespace:osc +RegisterMessageFunction osc/oscPack/osc/MessageMappingOscPacketListener.h /^ void RegisterMessageFunction( const char *addressPattern, function_type f )$/;" f class:osc::MessageMappingOscPacketListener +Reveal Reveal.cpp /^Reveal::Reveal() : GroupModule() {$/;" f class:Reveal +Reveal Reveal.hpp /^ Reveal();$/;" p class:Reveal +Reveal Reveal.hpp /^class Reveal : public GroupModule {$/;" c +Reveal_h Reveal.hpp 25;" d +RevealedCutModule modules/RevealedCutModule.cpp /^RevealedCutModule::RevealedCutModule(): ShapeModule(), RevealedModule() {$/;" f class:RevealedCutModule +RevealedCutModule modules/RevealedCutModule.hpp /^ RevealedCutModule();$/;" p class:RevealedCutModule +RevealedCutModule modules/RevealedCutModule.hpp /^class RevealedCutModule : public ShapeModule, public RevealedModule {$/;" c +RevealedCutModule_h modules/RevealedCutModule.hpp 25;" d +RevealedLayer modules/RevealedModule.cpp /^RevealedLayer::RevealedLayer(): m_playing(false), m_speed(1), $/;" f class:RevealedLayer +RevealedLayer modules/RevealedModule.hpp /^ RevealedLayer();$/;" p class:RevealedLayer +RevealedLayer modules/RevealedModule.hpp /^class RevealedLayer {$/;" c +RevealedLayerAnim modules/RevealedModule.cpp /^RevealedLayerAnim::RevealedLayerAnim():RevealedLayer() {$/;" f class:RevealedLayerAnim +RevealedLayerAnim modules/RevealedModule.hpp /^ RevealedLayerAnim();$/;" p class:RevealedLayerAnim +RevealedLayerAnim modules/RevealedModule.hpp /^class RevealedLayerAnim : public RevealedLayer {$/;" c +RevealedLayerImage modules/RevealedModule.hpp /^ RevealedLayerImage():RevealedLayer(){}$/;" f class:RevealedLayerImage +RevealedLayerImage modules/RevealedModule.hpp /^class RevealedLayerImage : public RevealedLayer {$/;" c +RevealedLayerVideo modules/RevealedModule.hpp /^ RevealedLayerVideo():RevealedLayer(){}$/;" f class:RevealedLayerVideo +RevealedLayerVideo modules/RevealedModule.hpp /^class RevealedLayerVideo: public RevealedLayer {$/;" c +RevealedModelModule modules/RevealedModelModule.cpp /^RevealedModelModule::RevealedModelModule(): ModelModule(), RevealedModule(){$/;" f class:RevealedModelModule +RevealedModelModule modules/RevealedModelModule.hpp /^ RevealedModelModule();$/;" p class:RevealedModelModule +RevealedModelModule modules/RevealedModelModule.hpp /^class RevealedModelModule : public ModelModule, public RevealedModule {$/;" c +RevealedModelModule_h modules/RevealedModelModule.hpp 25;" d +RevealedModule modules/RevealedModule.cpp /^RevealedModule::RevealedModule(): GeomModule(), $/;" f class:RevealedModule +RevealedModule modules/RevealedModule.hpp /^ RevealedModule();$/;" p class:RevealedModule +RevealedModule modules/RevealedModule.hpp /^class RevealedModule : public virtual GeomModule {$/;" c +RevealedModule_h modules/RevealedModule.hpp 25;" d +RevealedPathModule modules/RevealedPathModule.cpp /^RevealedPathModule::RevealedPathModule(): RevealedModule() {$/;" f class:RevealedPathModule +RevealedPathModule modules/RevealedPathModule.hpp /^ RevealedPathModule();$/;" p class:RevealedPathModule +RevealedPathModule modules/RevealedPathModule.hpp /^class RevealedPathModule : public RevealedModule, public ModuleListObserver {$/;" c +RevealedPathModule_h modules/RevealedPathModule.hpp 25;" d +RevealedShapeModule modules/RevealedShapeModule.cpp /^RevealedShapeModule::RevealedShapeModule(): ShapeModule(), RevealedModule(){$/;" f class:RevealedShapeModule +RevealedShapeModule modules/RevealedShapeModule.hpp /^ RevealedShapeModule();$/;" p class:RevealedShapeModule +RevealedShapeModule modules/RevealedShapeModule.hpp /^class RevealedShapeModule : public ShapeModule, public RevealedModule {$/;" c +RevealedShapeModule_h modules/RevealedShapeModule.hpp 25;" d +RevealedTextModule modules/RevealedTextModule.cpp /^RevealedTextModule::RevealedTextModule(): ShapeModule(), RevealedModule() {$/;" f class:RevealedTextModule +RevealedTextModule modules/RevealedTextModule.hpp /^ RevealedTextModule();$/;" p class:RevealedTextModule +RevealedTextModule modules/RevealedTextModule.hpp /^class RevealedTextModule : public ShapeModule, public RevealedModule {$/;" c +RevealedTextModule_h modules/RevealedTextModule.hpp 25;" d +RgbaColor osc/oscPack/osc/OscTypes.h /^ RgbaColor() {}$/;" f struct:osc::RgbaColor +RgbaColor osc/oscPack/osc/OscTypes.h /^ explicit RgbaColor( uint32 value_ ) : value( value_ ) {}$/;" f struct:osc::RgbaColor +RgbaColor osc/oscPack/osc/OscTypes.h /^struct RgbaColor{$/;" s namespace:osc +RootSceneGroupModule modules/RootSceneGroupModule.cpp /^RootSceneGroupModule::RootSceneGroupModule(): GroupModule() {$/;" f class:RootSceneGroupModule +RootSceneGroupModule modules/RootSceneGroupModule.hpp /^ RootSceneGroupModule();$/;" p class:RootSceneGroupModule +RootSceneGroupModule modules/RootSceneGroupModule.hpp /^class RootSceneGroupModule: public GroupModule {$/;" c +RootSceneGroupModule_h modules/RootSceneGroupModule.hpp 24;" d +RoundUp4 osc/oscPack/osc/OscOutboundPacketStream.cpp /^static inline std::size_t RoundUp4( std::size_t x ) $/;" f namespace:osc +RoundUp4 osc/oscPack/osc/OscReceivedElements.cpp /^static inline uint32 RoundUp4( uint32 x ) $/;" f namespace:osc +Run osc/oscPack/ip/UdpSocket.h /^ void Run() { mux_.Run(); }$/;" f class:UdpListeningReceiveSocket +Run osc/oscPack/ip/UdpSocket.h /^ void Run(); \/\/ loop and block processing messages indefinitely$/;" p class:SocketReceiveMultiplexer +Run osc/oscPack/ip/posix/UdpSocket.cpp /^ void Run()$/;" f class:SocketReceiveMultiplexer::Implementation +Run osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::Run()$/;" f class:SocketReceiveMultiplexer +Run osc/oscPack/ip/win32/UdpSocket.cpp /^ void Run()$/;" f class:SocketReceiveMultiplexer::Implementation +Run osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::Run()$/;" f class:SocketReceiveMultiplexer +RunUntilSigInt osc/oscPack/ip/UdpSocket.h /^ void RunUntilSigInt() { mux_.RunUntilSigInt(); }$/;" f class:UdpListeningReceiveSocket +RunUntilSigInt osc/oscPack/ip/UdpSocket.h /^ void RunUntilSigInt();$/;" p class:SocketReceiveMultiplexer +RunUntilSigInt osc/oscPack/ip/posix/UdpSocket.cpp /^void SocketReceiveMultiplexer::RunUntilSigInt()$/;" f class:SocketReceiveMultiplexer +RunUntilSigInt osc/oscPack/ip/win32/UdpSocket.cpp /^void SocketReceiveMultiplexer::RunUntilSigInt()$/;" f class:SocketReceiveMultiplexer +SELECTPROG Reveal.hpp /^ PREVIEWPROG, SLICEPROG, SELECTPROG, RENDERPROG, CALIBPROG$/;" e enum:Reveal::REVIL_PROGRAM +SELECTTEX Reveal.hpp /^ OUTPUTTEX, SLICETEX, SELECTTEX, INSIDETEX, SURFACETEX, COORDSTEX,$/;" e enum:Reveal::REVIL_UNIFORM +SHAPECOLOR Reveal.hpp /^ SHAPECOLOR, SHAPEID, SHAPEIDBIT, SUBSHAPEID, SUBSHAPESNB, $/;" e enum:Reveal::REVIL_UNIFORM +SHAPEID Reveal.hpp /^ SHAPECOLOR, SHAPEID, SHAPEIDBIT, SUBSHAPEID, SUBSHAPESNB, $/;" e enum:Reveal::REVIL_UNIFORM +SHAPEIDBIT Reveal.hpp /^ SHAPECOLOR, SHAPEID, SHAPEIDBIT, SUBSHAPEID, SUBSHAPESNB, $/;" e enum:Reveal::REVIL_UNIFORM +SLICEPROG Reveal.hpp /^ PREVIEWPROG, SLICEPROG, SELECTPROG, RENDERPROG, CALIBPROG$/;" e enum:Reveal::REVIL_PROGRAM +SLICETEX Reveal.hpp /^ OUTPUTTEX, SLICETEX, SELECTTEX, INSIDETEX, SURFACETEX, COORDSTEX,$/;" e enum:Reveal::REVIL_UNIFORM +STRING_ATTRIBUTE modules/Attribute.hpp /^ STRING_ATTRIBUTE, $/;" e enum:Attribute::TYPE +STRING_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ STRING_TYPE_TAG = 's',$/;" e enum:osc::TypeTagValues +SUBSHAPEID Reveal.hpp /^ SHAPECOLOR, SHAPEID, SHAPEIDBIT, SUBSHAPEID, SUBSHAPESNB, $/;" e enum:Reveal::REVIL_UNIFORM +SUBSHAPESNB Reveal.hpp /^ SHAPECOLOR, SHAPEID, SHAPEIDBIT, SUBSHAPEID, SUBSHAPESNB, $/;" e enum:Reveal::REVIL_UNIFORM +SURFACE Reveal.hpp /^ INSIDE, SURFACE, GRADIENTTYPE, SURFACETHICKNESS,$/;" e enum:Reveal::REVIL_UNIFORM +SURFACETEX Reveal.hpp /^ OUTPUTTEX, SLICETEX, SELECTTEX, INSIDETEX, SURFACETEX, COORDSTEX,$/;" e enum:Reveal::REVIL_UNIFORM +SURFACETHICKNESS Reveal.hpp /^ INSIDE, SURFACE, GRADIENTTYPE, SURFACETHICKNESS,$/;" e enum:Reveal::REVIL_UNIFORM +SYMBOL_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ SYMBOL_TYPE_TAG = 'S',$/;" e enum:osc::TypeTagValues +SceneGroupModule modules/SceneGroupModule.cpp /^SceneGroupModule::SceneGroupModule(): RootSceneGroupModule() {$/;" f class:SceneGroupModule +SceneGroupModule modules/SceneGroupModule.hpp /^ SceneGroupModule();$/;" p class:SceneGroupModule +SceneGroupModule modules/SceneGroupModule.hpp /^class SceneGroupModule: public RootSceneGroupModule {$/;" c +SceneGroupModule_h modules/SceneGroupModule.hpp 24;" d +Send osc/oscPack/ip/UdpSocket.h /^ void Send( const char *data, std::size_t size );$/;" p class:UdpSocket +Send osc/oscPack/ip/posix/UdpSocket.cpp /^ void Send( const char *data, std::size_t size )$/;" f class:UdpSocket::Implementation +Send osc/oscPack/ip/posix/UdpSocket.cpp /^void UdpSocket::Send( const char *data, std::size_t size )$/;" f class:UdpSocket +Send osc/oscPack/ip/win32/UdpSocket.cpp /^ void Send( const char *data, std::size_t size )$/;" f class:UdpSocket::Implementation +Send osc/oscPack/ip/win32/UdpSocket.cpp /^void UdpSocket::Send( const char *data, std::size_t size )$/;" f class:UdpSocket +SendTo osc/oscPack/ip/UdpSocket.h /^ void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size );$/;" p class:UdpSocket +SendTo osc/oscPack/ip/posix/UdpSocket.cpp /^ void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size )$/;" f class:UdpSocket::Implementation +SendTo osc/oscPack/ip/posix/UdpSocket.cpp /^void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size )$/;" f class:UdpSocket +SendTo osc/oscPack/ip/win32/UdpSocket.cpp /^ void SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size )$/;" f class:UdpSocket::Implementation +SendTo osc/oscPack/ip/win32/UdpSocket.cpp /^void UdpSocket::SendTo( const IpEndpointName& remoteEndpoint, const char *data, std::size_t size )$/;" f class:UdpSocket +SetAllowReuse osc/oscPack/ip/UdpSocket.h /^ void SetAllowReuse( bool allowReuse );$/;" p class:UdpSocket +SetAllowReuse osc/oscPack/ip/posix/UdpSocket.cpp /^ void SetAllowReuse( bool allowReuse )$/;" f class:UdpSocket::Implementation +SetAllowReuse osc/oscPack/ip/posix/UdpSocket.cpp /^void UdpSocket::SetAllowReuse( bool allowReuse )$/;" f class:UdpSocket +SetAllowReuse osc/oscPack/ip/win32/UdpSocket.cpp /^ void SetAllowReuse( bool allowReuse )$/;" f class:UdpSocket::Implementation +SetAllowReuse osc/oscPack/ip/win32/UdpSocket.cpp /^void UdpSocket::SetAllowReuse( bool allowReuse )$/;" f class:UdpSocket +SetEnableBroadcast osc/oscPack/ip/UdpSocket.h /^ void SetEnableBroadcast( bool enableBroadcast );$/;" p class:UdpSocket +SetEnableBroadcast osc/oscPack/ip/posix/UdpSocket.cpp /^ void SetEnableBroadcast( bool enableBroadcast )$/;" f class:UdpSocket::Implementation +SetEnableBroadcast osc/oscPack/ip/posix/UdpSocket.cpp /^void UdpSocket::SetEnableBroadcast( bool enableBroadcast )$/;" f class:UdpSocket +SetEnableBroadcast osc/oscPack/ip/win32/UdpSocket.cpp /^ void SetEnableBroadcast( bool enableBroadcast )$/;" f class:UdpSocket::Implementation +SetEnableBroadcast osc/oscPack/ip/win32/UdpSocket.cpp /^void UdpSocket::SetEnableBroadcast( bool enableBroadcast )$/;" f class:UdpSocket +ShapeModule modules/ShapeModule.cpp /^ShapeModule::ShapeModule(): GeomModule() {$/;" f class:ShapeModule +ShapeModule modules/ShapeModule.hpp /^ ShapeModule();$/;" p class:ShapeModule +ShapeModule modules/ShapeModule.hpp /^class ShapeModule : public virtual GeomModule {$/;" c +ShapeModule_h modules/ShapeModule.hpp 25;" d +Size osc/oscPack/osc/OscOutboundPacketStream.cpp /^std::size_t OutboundPacketStream::Size() const$/;" f class:osc::OutboundPacketStream +Size osc/oscPack/osc/OscOutboundPacketStream.h /^ std::size_t Size() const;$/;" p class:osc::OutboundPacketStream +Size osc/oscPack/osc/OscReceivedElements.cpp /^osc_bundle_element_size_t ReceivedBundleElement::Size() const$/;" f class:osc::ReceivedBundleElement +Size osc/oscPack/osc/OscReceivedElements.h /^ osc_bundle_element_size_t Size() const { return size_; }$/;" f class:osc::ReceivedPacket +Size osc/oscPack/osc/OscReceivedElements.h /^ osc_bundle_element_size_t Size() const;$/;" p class:osc::ReceivedBundleElement +SockaddrFromIpEndpointName osc/oscPack/ip/posix/UdpSocket.cpp /^static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )$/;" f file: +SockaddrFromIpEndpointName osc/oscPack/ip/win32/UdpSocket.cpp /^static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )$/;" f file: +Socket osc/oscPack/ip/posix/UdpSocket.cpp /^ int Socket() { return socket_; }$/;" f class:UdpSocket::Implementation +Socket osc/oscPack/ip/win32/UdpSocket.cpp /^ SOCKET& Socket() { return socket_; }$/;" f class:UdpSocket::Implementation +SocketReceiveMultiplexer osc/oscPack/ip/UdpSocket.h /^ SocketReceiveMultiplexer();$/;" p class:SocketReceiveMultiplexer +SocketReceiveMultiplexer osc/oscPack/ip/UdpSocket.h /^class SocketReceiveMultiplexer{$/;" c +SocketReceiveMultiplexer osc/oscPack/ip/posix/UdpSocket.cpp /^SocketReceiveMultiplexer::SocketReceiveMultiplexer()$/;" f class:SocketReceiveMultiplexer +SocketReceiveMultiplexer osc/oscPack/ip/win32/UdpSocket.cpp /^SocketReceiveMultiplexer::SocketReceiveMultiplexer()$/;" f class:SocketReceiveMultiplexer +SpaceModule modules/SpaceModule.cpp /^SpaceModule::SpaceModule(): DepthGroupModule() {$/;" f class:SpaceModule +SpaceModule modules/SpaceModule.hpp /^ SpaceModule();$/;" p class:SpaceModule +SpaceModule modules/SpaceModule.hpp /^class SpaceModule : public DepthGroupModule {$/;" c +SpaceModule_h modules/SpaceModule.hpp 25;" d +SpacesModule modules/SpaceModule.hpp /^ SpacesModule(): GroupModule() {$/;" f class:SpacesModule +SpacesModule modules/SpaceModule.hpp /^class SpacesModule: public GroupModule {$/;" c +SphereGeometry geoms/SphereGeometry.cpp /^SphereGeometry::SphereGeometry(): Geometry() {$/;" f class:SphereGeometry +SphereGeometry geoms/SphereGeometry.hpp /^ SphereGeometry();$/;" p class:SphereGeometry +SphereGeometry geoms/SphereGeometry.hpp /^class SphereGeometry : public Geometry {$/;" c +SphereGeometry_h geoms/SphereGeometry.hpp 25;" d +StringCallback modules/Attribute.hpp /^ typedef void (StringCallback) (Module*,const std::vector<std::string>&);$/;" t class:Attribute +Symbol osc/oscPack/osc/OscTypes.h /^ Symbol() {}$/;" f struct:osc::Symbol +Symbol osc/oscPack/osc/OscTypes.h /^ explicit Symbol( const char* value_ ) : value( value_ ) {}$/;" f struct:osc::Symbol +Symbol osc/oscPack/osc/OscTypes.h /^struct Symbol{$/;" s namespace:osc +TEXOFFSET Reveal.hpp /^ TEXOFFSET, TEXSCALE,$/;" e enum:Reveal::REVIL_UNIFORM +TEXSCALE Reveal.hpp /^ TEXOFFSET, TEXSCALE,$/;" e enum:Reveal::REVIL_UNIFORM +TIME_TAG_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ TIME_TAG_TYPE_TAG = 't',$/;" e enum:osc::TypeTagValues +TRUE_TYPE_TAG osc/oscPack/osc/OscTypes.h /^ TRUE_TYPE_TAG = 'T',$/;" e enum:osc::TypeTagValues +TYPE modules/Attribute.hpp /^ enum TYPE {FLOAT_ATTRIBUTE, $/;" g class:Attribute +TimeTag osc/oscPack/osc/OscReceivedElements.cpp /^uint64 ReceivedBundle::TimeTag() const$/;" f class:osc::ReceivedBundle +TimeTag osc/oscPack/osc/OscReceivedElements.h /^ uint64 TimeTag() const;$/;" p class:osc::ReceivedBundle +TimeTag osc/oscPack/osc/OscTypes.h /^ TimeTag() {}$/;" f struct:osc::TimeTag +TimeTag osc/oscPack/osc/OscTypes.h /^ explicit TimeTag( uint64 value_ ) : value( value_ ) {}$/;" f struct:osc::TimeTag +TimeTag osc/oscPack/osc/OscTypes.h /^struct TimeTag{$/;" s namespace:osc +TimerExpired osc/oscPack/ip/TimerListener.h /^ virtual void TimerExpired() = 0;$/;" p class:TimerListener +TimerListener osc/oscPack/ip/TimerListener.h /^class TimerListener{$/;" c +ToInt32 osc/oscPack/osc/OscReceivedElements.cpp /^static inline int32 ToInt32( const char *p )$/;" f namespace:osc +ToInt64 osc/oscPack/osc/OscReceivedElements.cpp /^static inline int64 ToInt64( const char *p )$/;" f namespace:osc +ToUInt32 osc/oscPack/osc/OscReceivedElements.cpp /^static inline uint32 ToUInt32( const char *p )$/;" f namespace:osc +ToUInt64 osc/oscPack/osc/OscReceivedElements.cpp /^static inline uint64 ToUInt64( const char *p )$/;" f namespace:osc +Tracker modules/DepthCamModule.hpp /^class Tracker {$/;" c +TubeGeometry geoms/TubeGeometry.cpp /^TubeGeometry::TubeGeometry(): Geometry() {$/;" f class:TubeGeometry +TubeGeometry geoms/TubeGeometry.hpp /^ TubeGeometry();$/;" p class:TubeGeometry +TubeGeometry geoms/TubeGeometry.hpp /^class TubeGeometry : public Geometry {$/;" c +TubeGeometry_h geoms/TubeGeometry.hpp 25;" d +TypeTag osc/oscPack/osc/OscReceivedElements.h /^ char TypeTag() const { return *typeTagPtr_; }$/;" f class:osc::ReceivedMessageArgument +TypeTagValues osc/oscPack/osc/OscTypes.h /^enum TypeTagValues {$/;" g namespace:osc +TypeTags osc/oscPack/osc/OscReceivedElements.h /^ const char *TypeTags() const { return typeTagsBegin_; }$/;" f class:osc::ReceivedMessage +UdpListeningReceiveSocket osc/oscPack/ip/UdpSocket.h /^ UdpListeningReceiveSocket( const IpEndpointName& localEndpoint, PacketListener *listener )$/;" f class:UdpListeningReceiveSocket +UdpListeningReceiveSocket osc/oscPack/ip/UdpSocket.h /^class UdpListeningReceiveSocket : public UdpSocket{$/;" c +UdpReceiveSocket osc/oscPack/ip/UdpSocket.h /^ UdpReceiveSocket( const IpEndpointName& localEndpoint )$/;" f class:UdpReceiveSocket +UdpReceiveSocket osc/oscPack/ip/UdpSocket.h /^class UdpReceiveSocket : public UdpSocket{$/;" c +UdpSocket osc/oscPack/ip/UdpSocket.h /^ UdpSocket();$/;" p class:UdpSocket +UdpSocket osc/oscPack/ip/UdpSocket.h /^class UdpSocket{$/;" c +UdpSocket osc/oscPack/ip/posix/UdpSocket.cpp /^UdpSocket::UdpSocket()$/;" f class:UdpSocket +UdpSocket osc/oscPack/ip/win32/UdpSocket.cpp /^UdpSocket::UdpSocket()$/;" f class:UdpSocket +UdpTransmitSocket osc/oscPack/ip/UdpSocket.h /^ UdpTransmitSocket( const IpEndpointName& remoteEndpoint )$/;" f class:UdpTransmitSocket +UdpTransmitSocket osc/oscPack/ip/UdpSocket.h /^class UdpTransmitSocket : public UdpSocket{$/;" c +VIEWMAT Reveal.hpp /^ VIEWMAT, VIEWPROJMAT, MODELMAT, MIRRORED, $/;" e enum:Reveal::REVIL_UNIFORM +VIEWPORTHEIGHT Reveal.hpp /^ VIEWPORTWIDTH, VIEWPORTHEIGHT, $/;" e enum:Reveal::REVIL_UNIFORM +VIEWPORTWIDTH Reveal.hpp /^ VIEWPORTWIDTH, VIEWPORTHEIGHT, $/;" e enum:Reveal::REVIL_UNIFORM +VIEWPROJMAT Reveal.hpp /^ VIEWMAT, VIEWPROJMAT, MODELMAT, MIRRORED, $/;" e enum:Reveal::REVIL_UNIFORM +VISIBLE_FROM Reveal.hpp /^ enum VISIBLE_FROM {$/;" g class:Reveal +VISIBLE_FROM_ALL Reveal.hpp /^ VISIBLE_FROM_NONE, VISIBLE_FROM_ALL$/;" e enum:Reveal::VISIBLE_FROM +VISIBLE_FROM_NONE Reveal.hpp /^ VISIBLE_FROM_NONE, VISIBLE_FROM_ALL$/;" e enum:Reveal::VISIBLE_FROM +ValidateSize osc/oscPack/osc/OscReceivedElements.h /^ static osc_bundle_element_size_t ValidateSize( osc_bundle_element_size_t size )$/;" f class:osc::ReceivedPacket +ValueTypeSizes osc/oscPack/osc/OscTypes.h /^enum ValueTypeSizes{$/;" g namespace:osc +WrongArgumentTypeException osc/oscPack/osc/OscReceivedElements.h /^ WrongArgumentTypeException( const char *w="wrong argument type" )$/;" f class:osc::WrongArgumentTypeException +WrongArgumentTypeException osc/oscPack/osc/OscReceivedElements.h /^class WrongArgumentTypeException : public Exception{$/;" c namespace:osc +_RINGBUFFER_H osc/ringbuffer.h 22;" d +absPositionCallback modules/Module.hpp /^ static void absPositionCallback(Module* mod, $/;" f class:Module +activateColor modules/DepthCamModule.cpp /^void DepthCamModule::activateColor() {$/;" f class:DepthCamModule +activateColor modules/DepthCamModule.hpp /^ void activateColor();$/;" p class:DepthCamModule +activeCallback modules/PreviewModule.hpp /^ static void activeCallback(Module* mod, $/;" f class:PreviewModule +activeCallback modules/ProjectorModule.hpp /^ static void activeCallback(Module* mod, $/;" f class:ProjectorModule +addAttribute modules/Module.hpp /^ inline void addAttribute(Attribute* attr) { $/;" f class:Module +addCam modules/DepthGroupModule.cpp /^void DepthGroupModule::addCam() {$/;" f class:DepthGroupModule +addCam modules/DepthGroupModule.hpp /^ void addCam();$/;" p class:DepthGroupModule +addCamCallback modules/DepthGroupModule.hpp /^ static void addCamCallback(Module* mod) {$/;" f class:DepthGroupModule +addChild modules/DepthGroupModule.cpp /^void DepthGroupModule::addChild(Module* mod) {$/;" f class:DepthGroupModule +addChild modules/DepthGroupModule.hpp /^ virtual void addChild(Module*);$/;" p class:DepthGroupModule +addChild modules/GroupModule.cpp /^void GroupModule::addChild(Module* mod) {$/;" f class:GroupModule +addChild modules/GroupModule.hpp /^ virtual void addChild(Module* mod);$/;" p class:GroupModule +addChild modules/SpaceModule.cpp /^void SpaceModule::addChild(Module* mod) {$/;" f class:SpaceModule +addChild modules/SpaceModule.hpp /^ virtual void addChild(Module* mod);$/;" p class:SpaceModule +addContextHandler Reveal.cpp /^void Reveal::addContextHandler(ContextHandler* cont) {$/;" f class:Reveal +addContextHandler Reveal.hpp /^ void addContextHandler(ContextHandler* cont);$/;" p class:Reveal +addCut modules/RootSceneGroupModule.cpp /^void RootSceneGroupModule::addCut(const std::string& name) {$/;" f class:RootSceneGroupModule +addCut modules/RootSceneGroupModule.hpp /^ void addCut(const std::string&);$/;" p class:RootSceneGroupModule +addCutCallback modules/RootSceneGroupModule.hpp /^ static void addCutCallback(Module* mod,$/;" f class:RootSceneGroupModule +addDepthGroup modules/DepthGroupModule.cpp /^void DepthGroupModule::addDepthGroup(const string& name) {$/;" f class:DepthGroupModule +addDepthGroup modules/DepthGroupModule.hpp /^ void addDepthGroup(const std::string& name);$/;" p class:DepthGroupModule +addDepthGroupCallback modules/DepthGroupModule.hpp /^ static void addDepthGroupCallback(Module* mod,$/;" f class:DepthGroupModule +addDepthMesh modules/DepthGroupModule.cpp /^void DepthGroupModule::addDepthMesh(const string& name) {$/;" f class:DepthGroupModule +addDepthMesh modules/DepthGroupModule.hpp /^ void addDepthMesh(const std::string& name);$/;" p class:DepthGroupModule +addDepthMeshCallback modules/DepthGroupModule.hpp /^ static void addDepthMeshCallback(Module* mod,$/;" f class:DepthGroupModule +addDepthShape modules/DepthGroupModule.cpp /^void DepthGroupModule::addDepthShape(const string& name) {$/;" f class:DepthGroupModule +addDepthShape modules/DepthGroupModule.hpp /^ void addDepthShape(const std::string& name);$/;" p class:DepthGroupModule +addDepthShapeCallback modules/DepthGroupModule.hpp /^ static void addDepthShapeCallback(Module* mod, $/;" f class:DepthGroupModule +addGroup modules/RootSceneGroupModule.cpp /^void RootSceneGroupModule::addGroup(const std::string& name) {$/;" f class:RootSceneGroupModule +addGroup modules/RootSceneGroupModule.hpp /^ void addGroup(const std::string&);$/;" p class:RootSceneGroupModule +addGroupAttributes modules/RootSceneGroupModule.cpp /^void RootSceneGroupModule::addGroupAttributes() {$/;" f class:RootSceneGroupModule +addGroupAttributes modules/RootSceneGroupModule.hpp /^ void addGroupAttributes();$/;" p class:RootSceneGroupModule +addGroupCallback modules/RootSceneGroupModule.hpp /^ static void addGroupCallback(Module* mod,$/;" f class:RootSceneGroupModule +addListener modules/Attribute.cpp /^void Attribute::addListener(Listener* lis) {$/;" f class:Attribute +addListener modules/Attribute.hpp /^ void addListener(Listener*);$/;" p class:Attribute +addModel modules/RootSceneGroupModule.cpp /^void RootSceneGroupModule::addModel(const std::string& name) {$/;" f class:RootSceneGroupModule +addModel modules/RootSceneGroupModule.hpp /^ void addModel(const std::string&);$/;" p class:RootSceneGroupModule +addModelAttributes modules/ModelModule.cpp /^void ModelModule::addModelAttributes() {$/;" f class:ModelModule +addModelAttributes modules/ModelModule.hpp /^ void addModelAttributes();$/;" p class:ModelModule +addModelCallback modules/RootSceneGroupModule.hpp /^ static void addModelCallback(Module* mod,$/;" f class:RootSceneGroupModule +addModuleListObserver Reveal.cpp /^void Reveal::addModuleListObserver(ModuleListObserver* obs) {$/;" f class:Reveal +addModuleListObserver Reveal.hpp /^ void addModuleListObserver(ModuleListObserver* obs);$/;" p class:Reveal +addModulePoint modules/RevealedPathModule.cpp /^void RevealedPathModule::addModulePoint(const std::string& moduleStr) {$/;" f class:RevealedPathModule +addModulePoint modules/RevealedPathModule.hpp /^ void addModulePoint(const std::string&);$/;" p class:RevealedPathModule +addModulePointCallback modules/RevealedPathModule.hpp /^ static void addModulePointCallback(Module* mod,$/;" f class:RevealedPathModule +addNameAttribute modules/Module.cpp /^void Module::addNameAttribute() {$/;" f class:Module +addNameAttribute modules/Module.hpp /^ virtual void addNameAttribute();$/;" p class:Module +addPath modules/RootSceneGroupModule.cpp /^void RootSceneGroupModule::addPath(const std::string& name) {$/;" f class:RootSceneGroupModule +addPath modules/RootSceneGroupModule.hpp /^ void addPath(const std::string&);$/;" p class:RootSceneGroupModule +addPathCallback modules/RootSceneGroupModule.hpp /^ static void addPathCallback(Module* mod,$/;" f class:RootSceneGroupModule +addPoint modules/RevealedPathModule.cpp /^void RevealedPathModule::addPoint(const float& x, $/;" f class:RevealedPathModule +addPoint modules/RevealedPathModule.hpp /^ void addPoint(const float& x, const float& y, const float& z);$/;" p class:RevealedPathModule +addPointCallback modules/RevealedPathModule.hpp /^ static void addPointCallback(Module* mod, $/;" f class:RevealedPathModule +addProj modules/DepthGroupModule.cpp /^void DepthGroupModule::addProj() {$/;" f class:DepthGroupModule +addProj modules/DepthGroupModule.hpp /^ void addProj();$/;" p class:DepthGroupModule +addProjCallback modules/DepthGroupModule.hpp /^ static void addProjCallback(Module* mod) {$/;" f class:DepthGroupModule +addRemoveAttribute modules/Module.cpp /^void Module::addRemoveAttribute() {$/;" f class:Module +addRemoveAttribute modules/Module.hpp /^ virtual void addRemoveAttribute();$/;" p class:Module +addRevealedAttributes modules/RevealedModule.cpp /^void RevealedModule::addRevealedAttributes() {$/;" f class:RevealedModule +addRevealedAttributes modules/RevealedModule.hpp /^ void addRevealedAttributes();$/;" p class:RevealedModule +addRevealedByAttribute modules/Module.cpp /^void Module::addRevealedByAttribute() {$/;" f class:Module +addRevealedByAttribute modules/Module.hpp /^ virtual void addRevealedByAttribute();$/;" p class:Module +addRevealedInsideAttributes modules/RevealedModule.cpp /^void RevealedModule::addRevealedInsideAttributes() {$/;" f class:RevealedModule +addRevealedInsideAttributes modules/RevealedModule.hpp /^ void addRevealedInsideAttributes();$/;" p class:RevealedModule +addRevealedOutputAttributes modules/RevealedModule.cpp /^void RevealedModule::addRevealedOutputAttributes() {$/;" f class:RevealedModule +addRevealedOutputAttributes modules/RevealedModule.hpp /^ void addRevealedOutputAttributes();$/;" p class:RevealedModule +addShape modules/RootSceneGroupModule.cpp /^void RootSceneGroupModule::addShape(const std::string& name) {$/;" f class:RootSceneGroupModule +addShape modules/RootSceneGroupModule.hpp /^ void addShape(const std::string&);$/;" p class:RootSceneGroupModule +addShapeAttributes modules/ShapeModule.cpp /^void ShapeModule::addShapeAttributes() {$/;" f class:ShapeModule +addShapeAttributes modules/ShapeModule.hpp /^ void addShapeAttributes();$/;" p class:ShapeModule +addShapeCallback modules/RootSceneGroupModule.hpp /^ static void addShapeCallback(Module* mod,$/;" f class:RootSceneGroupModule +addSpace modules/SpaceModule.cpp /^void SpacesModule::addSpace() {$/;" f class:SpacesModule +addSpace modules/SpaceModule.hpp /^ void addSpace();$/;" p class:SpacesModule +addSpaceCallback modules/SpaceModule.hpp /^ static void addSpaceCallback(Module* mod) {$/;" f class:SpacesModule +addSpaceModule modules/SpaceModule.cpp /^void SpaceModule::addSpaceModule(Module* mod) {$/;" f class:SpaceModule +addSpaceModule modules/SpaceModule.hpp /^ void addSpaceModule(Module*);$/;" p class:SpaceModule +addText modules/RootSceneGroupModule.cpp /^void RootSceneGroupModule::addText(const std::string& name) {$/;" f class:RootSceneGroupModule +addText modules/RootSceneGroupModule.hpp /^ void addText(const std::string&);$/;" p class:RootSceneGroupModule +addTextCallback modules/RootSceneGroupModule.hpp /^ static void addTextCallback(Module* mod,$/;" f class:RootSceneGroupModule +addTransformationAttributes modules/Module.cpp /^void Module::addTransformationAttributes() {$/;" f class:Module +addTransformationAttributes modules/Module.hpp /^ virtual void addTransformationAttributes();$/;" p class:Module +addUpdateObserver Reveal.cpp /^void Reveal::addUpdateObserver(Module* upObs) {$/;" f class:Reveal +addUpdateObserver Reveal.hpp /^ void addUpdateObserver(Module* upObs);$/;" p class:Reveal +addVertex modules/DepthMeshModule.cpp /^void DepthMeshModule::addVertex(const float& x, $/;" f class:DepthMeshModule +addVertex modules/DepthMeshModule.hpp /^ void addVertex(const float& z, const float& y, const float& x);$/;" p class:DepthMeshModule +addVertexCallback modules/DepthMeshModule.hpp /^ static void addVertexCallback(Module* mod,$/;" f class:DepthMeshModule +addVisibleAttribute modules/Module.cpp /^void Module::addVisibleAttribute() {$/;" f class:Module +addVisibleAttribute modules/Module.hpp /^ virtual void addVisibleAttribute();$/;" p class:Module +addVisibleFromAttribute modules/Module.cpp /^void Module::addVisibleFromAttribute() {$/;" f class:Module +addVisibleFromAttribute modules/Module.hpp /^ virtual void addVisibleFromAttribute();$/;" p class:Module +address osc/oscPack/ip/IpEndpointName.h /^ unsigned long address;$/;" m class:IpEndpointName +addressPattern osc/oscPack/osc/OscTypes.h /^ const char *addressPattern;$/;" m struct:osc::BeginMessage +addressPattern_ osc/oscPack/osc/OscReceivedElements.h /^ const char *addressPattern_;$/;" m class:osc::ReceivedMessage +animPlayCallback modules/RevealedModule.hpp /^ static void animPlayCallback(Module* mod, $/;" f class:RevealedModule +animPosCallback modules/RevealedModule.hpp /^ static void animPosCallback(Module* mod, $/;" f class:RevealedModule +animSpeedCallback modules/RevealedModule.hpp /^ static void animSpeedCallback(Module* mod, $/;" f class:RevealedModule +argumentCurrent_ osc/oscPack/osc/OscOutboundPacketStream.h /^ char *argumentCurrent_;$/;" m class:osc::OutboundPacketStream +argumentPtr_ osc/oscPack/osc/OscReceivedElements.h /^ const char *argumentPtr_;$/;" m class:osc::ReceivedMessageArgument +arguments_ osc/oscPack/osc/OscReceivedElements.h /^ const char *arguments_;$/;" m class:osc::ReceivedMessage +askQuit Reveal.cpp /^void Reveal::askQuit() {$/;" f class:Reveal +askQuit Reveal.hpp /^ void askQuit();$/;" p class:Reveal +attachProj modules/DepthCamModule.cpp /^void DepthCamModule::attachProj(ProjectorModule* proj) {$/;" f class:DepthCamModule +attachProj modules/DepthCamModule.hpp /^ void attachProj(ProjectorModule*);$/;" p class:DepthCamModule +attachToCam modules/ProjectorModule.cpp /^void ProjectorModule::attachToCam(const string& camName) {$/;" f class:ProjectorModule +attachToCam modules/ProjectorModule.hpp /^ void attachToCam(const std::string& camName);$/;" p class:ProjectorModule +attachToCamCallback modules/ProjectorModule.hpp /^ static void attachToCamCallback(Module* mod, $/;" f class:ProjectorModule +breakEvent_ osc/oscPack/ip/win32/UdpSocket.cpp /^ HANDLE breakEvent_;$/;" m class:SocketReceiveMultiplexer::Implementation file: +breakPipe_ osc/oscPack/ip/posix/UdpSocket.cpp /^ int breakPipe_[2]; \/\/ [0] is the reader descriptor and [1] the writer$/;" m class:SocketReceiveMultiplexer::Implementation file: +break_ osc/oscPack/ip/posix/UdpSocket.cpp /^ volatile bool break_;$/;" m class:SocketReceiveMultiplexer::Implementation file: +break_ osc/oscPack/ip/win32/UdpSocket.cpp /^ volatile bool break_;$/;" m class:SocketReceiveMultiplexer::Implementation file: +buf osc/ringbuffer.c /^ char *buf;$/;" m struct:__anon7 file: +buf osc/ringbuffer.c /^ char *buf;$/;" m struct:__anon6 file: +buf osc/ringbuffer.h /^ char *buf;$/;" m struct:__anon2 +buf osc/ringbuffer.h /^ char *buf;$/;" m struct:__anon1 +calculationCenterOfMarker modules/DepthCamModule.cpp /^cv::Point DepthCamModule::calculationCenterOfMarker(s_markerAndTime& marker){$/;" f class:DepthCamModule +calculationCenterOfMarker modules/DepthCamModule.hpp /^ cv::Point calculationCenterOfMarker(s_markerAndTime& marker);$/;" p class:DepthCamModule +calibrate modules/DepthCamModule.cpp /^void DepthCamModule::calibrate() {$/;" f class:DepthCamModule +calibrate modules/DepthCamModule.hpp /^ void calibrate();$/;" p class:DepthCamModule +calibrate modules/ProjectorModule.cpp /^void ProjectorModule::calibrate(const std::string& camName) {$/;" f class:ProjectorModule +calibrate modules/ProjectorModule.hpp /^ void calibrate(const std::string& camName);$/;" p class:ProjectorModule +calibrateCallback modules/ProjectorModule.hpp /^ static void calibrateCallback(Module* mod, $/;" f class:ProjectorModule +calibrationCallback modules/DepthCamModule.hpp /^ static void calibrationCallback(Module* mod) {$/;" f class:DepthCamModule +captureBackground modules/DepthCamModule.cpp /^void DepthCamModule::captureBackground() {$/;" f class:DepthCamModule +captureBackground modules/DepthCamModule.hpp /^ void captureBackground();$/;" p class:DepthCamModule +captureBackgroundCallback modules/DepthCamModule.hpp /^ static void captureBackgroundCallback(Module* mod,$/;" f class:DepthCamModule +cbAction gui/AttributeWidget.cpp /^void AttributeWidget::cbAction(Fl_Widget*) {$/;" f class:AttributeWidget +cbAction gui/AttributeWidget.hpp /^ void cbAction(Fl_Widget*);$/;" p class:AttributeWidget +cbAddListener gui/AttributeWidget.cpp /^void AttributeWidget::cbAddListener(Fl_Widget*) {$/;" f class:AttributeWidget +cbAddListener gui/AttributeWidget.hpp /^ void cbAddListener(Fl_Widget*);$/;" p class:AttributeWidget +cbCalib modules/DepthCamModule.cpp /^static void cbCalib(int c, void* mod) {$/;" f file: +cbCalib modules/ProjectorModule.cpp /^static void cbCalib(int c, void* mod) {$/;" f file: +cbChecks gui/AttributeWidget.cpp /^void AttributeWidget::cbChecks(Fl_Widget*) {$/;" f class:AttributeWidget +cbChecks gui/AttributeWidget.hpp /^ void cbChecks(Fl_Widget*);$/;" p class:AttributeWidget +cbChoices gui/AttributeWidget.cpp /^void AttributeWidget::cbChoices(Fl_Widget*) {$/;" f class:AttributeWidget +cbChoices gui/AttributeWidget.hpp /^ void cbChoices(Fl_Widget*);$/;" p class:AttributeWidget +cbFileOpen gui/AttributeWidget.cpp /^void AttributeWidget::cbFileOpen(Fl_Widget*) {$/;" f class:AttributeWidget +cbFileOpen gui/AttributeWidget.hpp /^ void cbFileOpen(Fl_Widget*);$/;" p class:AttributeWidget +cbFileSave gui/AttributeWidget.cpp /^void AttributeWidget::cbFileSave(Fl_Widget*) {$/;" f class:AttributeWidget +cbFileSave gui/AttributeWidget.hpp /^ void cbFileSave(Fl_Widget*);$/;" p class:AttributeWidget +cbFloats gui/AttributeWidget.cpp /^void AttributeWidget::cbFloats(Fl_Widget*) {$/;" f class:AttributeWidget +cbFloats gui/AttributeWidget.hpp /^ void cbFloats(Fl_Widget*);$/;" p class:AttributeWidget +cbFolderOpen gui/AttributeWidget.cpp /^void AttributeWidget::cbFolderOpen(Fl_Widget*) {$/;" f class:AttributeWidget +cbFolderOpen gui/AttributeWidget.hpp /^ void cbFolderOpen(Fl_Widget*);$/;" p class:AttributeWidget +cbInts gui/AttributeWidget.cpp /^void AttributeWidget::cbInts(Fl_Widget*) {$/;" f class:AttributeWidget +cbInts gui/AttributeWidget.hpp /^ void cbInts(Fl_Widget*);$/;" p class:AttributeWidget +cbMarkerPosY modules/DepthCamModule.cpp /^static void cbMarkerPosY(int y, void* mod) {$/;" f file: +cbMarkerRotX modules/DepthCamModule.cpp /^static void cbMarkerRotX(int x, void* mod) {$/;" f file: +cbMarkerRotY modules/DepthCamModule.cpp /^static void cbMarkerRotY(int y, void* mod) {$/;" f file: +cbOpen gui/MainWindow.cpp /^void MainWindow::cbOpen() {$/;" f class:MainWindow +cbOpen gui/MainWindow.hpp /^ void cbOpen();$/;" p class:MainWindow +cbParams gui/ListenerWidget.cpp /^void ListenerWidget::cbParams(Fl_Widget*) {$/;" f class:ListenerWidget +cbParams gui/ListenerWidget.hpp /^ void cbParams(Fl_Widget*);$/;" p class:ListenerWidget +cbPatternBrightness modules/ProjectorModule.cpp /^static void cbPatternBrightness(int b, void* mod) {$/;" f file: +cbPatternPosX modules/ProjectorModule.cpp /^static void cbPatternPosX(int x, void* mod) {$/;" f file: +cbPatternPosY modules/ProjectorModule.cpp /^static void cbPatternPosY(int y, void* mod) {$/;" f file: +cbPatternSquareWidth modules/ProjectorModule.cpp /^static void cbPatternSquareWidth(int w, void* mod) {$/;" f file: +cbPatternThresh modules/ProjectorModule.cpp /^static void cbPatternThresh(int x, void* mod) {$/;" f file: +cbQuit gui/MainWindow.cpp /^void MainWindow::cbQuit() {$/;" f class:MainWindow +cbQuit gui/MainWindow.hpp /^ void cbQuit();$/;" p class:MainWindow +cbRemove gui/ListenerWidget.cpp /^void ListenerWidget::cbRemove(Fl_Widget*) {$/;" f class:ListenerWidget +cbRemove gui/ListenerWidget.hpp /^ void cbRemove(Fl_Widget*);$/;" p class:ListenerWidget +cbSave gui/MainWindow.cpp /^void MainWindow::cbSave() {$/;" f class:MainWindow +cbSave gui/MainWindow.hpp /^ void cbSave();$/;" p class:MainWindow +cbSaveAs gui/MainWindow.cpp /^void MainWindow::cbSaveAs() {$/;" f class:MainWindow +cbSaveAs gui/MainWindow.hpp /^ void cbSaveAs();$/;" p class:MainWindow +cbShowListeners gui/AttributeWidget.cpp /^void AttributeWidget::cbShowListeners(Fl_Widget*) {$/;" f class:AttributeWidget +cbShowListeners gui/AttributeWidget.hpp /^ void cbShowListeners(Fl_Widget*);$/;" p class:AttributeWidget +cbStrings gui/AttributeWidget.cpp /^void AttributeWidget::cbStrings(Fl_Widget*) {$/;" f class:AttributeWidget +cbStrings gui/AttributeWidget.hpp /^ void cbStrings(Fl_Widget*);$/;" p class:AttributeWidget +cbTree gui/MainWindow.cpp /^void MainWindow::cbTree(Fl_Widget* w) {$/;" f class:MainWindow +cbTree gui/MainWindow.hpp /^ void cbTree(Fl_Widget*);$/;" p class:MainWindow +clearListeners modules/Attribute.cpp /^void Attribute::clearListeners() {$/;" f class:Attribute +clearListeners modules/Attribute.hpp /^ void clearListeners();$/;" p class:Attribute +clearPoints modules/RevealedPathModule.cpp /^void RevealedPathModule::clearPoints() {$/;" f class:RevealedPathModule +clearPoints modules/RevealedPathModule.hpp /^ void clearPoints();$/;" p class:RevealedPathModule +clearPointsCallback modules/RevealedPathModule.hpp /^ static void clearPointsCallback(Module* mod) {$/;" f class:RevealedPathModule +clearVertices modules/DepthMeshModule.cpp /^void DepthMeshModule::clearVertices() {$/;" f class:DepthMeshModule +clearVertices modules/DepthMeshModule.hpp /^ void clearVertices();$/;" p class:DepthMeshModule +clearVerticesCallback modules/DepthMeshModule.hpp /^ static void clearVerticesCallback(Module* mod) {$/;" f class:DepthMeshModule +closeDevice modules/DepthCamModule.cpp /^void DepthCamModule::closeDevice() {$/;" f class:DepthCamModule +closeDevice modules/DepthCamModule.hpp /^ void closeDevice();$/;" p class:DepthCamModule +colorCallback modules/RevealedModule.hpp /^ static void colorCallback(Module* mod, $/;" f class:RevealedModule +colorCamOpenCV modules/DepthCamModule.hpp /^ void colorCamOpenCV(void);$/;" p class:DepthCamModule +compare modules/ModelModule.hpp /^ bool compare(ModelVertex& v) {$/;" f struct:ModelModule::ModelVertex +computeNbPixPerRow modules/RevealedCutModule.cpp /^int CutWindow::computeNbPixPerRow(const int& srcW, const int& srcH) {$/;" f class:CutWindow +computeNbPixPerRow modules/RevealedCutModule.hpp /^ int computeNbPixPerRow(const int& srcW, const int& srcH);$/;" p class:CutWindow +connectedAddr_ osc/oscPack/ip/posix/UdpSocket.cpp /^ struct sockaddr_in connectedAddr_;$/;" m class:UdpSocket::Implementation typeref:struct:UdpSocket::Implementation::sockaddr_in file: +connectedAddr_ osc/oscPack/ip/win32/UdpSocket.cpp /^ struct sockaddr_in connectedAddr_;$/;" m class:UdpSocket::Implementation typeref:struct:UdpSocket::Implementation::sockaddr_in file: +const_iterator osc/oscPack/osc/OscReceivedElements.h /^ typedef ReceivedBundleElementIterator const_iterator;$/;" t class:osc::ReceivedBundle +const_iterator osc/oscPack/osc/OscReceivedElements.h /^ typedef ReceivedMessageArgumentIterator const_iterator;$/;" t class:osc::ReceivedMessage +contents_ osc/oscPack/osc/OscReceivedElements.h /^ const char *contents_;$/;" m class:osc::ReceivedPacket +contourThresholdCallback modules/DepthCamModule.hpp /^ static void contourThresholdCallback(Module* mod,$/;" f class:DepthCamModule +corners modules/DepthCamModule.hpp /^ std::vector<cv::Point2f> corners;$/;" m struct:s_markerAndTime +createListener Reveal.cpp /^Listener* Reveal::createListener(const std::string& typeStr) {$/;" f class:Reveal +createListener Reveal.hpp /^ Listener* createListener(const std::string& typeStr);$/;" p class:Reveal +createMatColor modules/DepthCamModule.cpp /^bool DepthCamModule::createMatColor(){$/;" f class:DepthCamModule +createMatColor modules/DepthCamModule.hpp /^ bool createMatColor();$/;" p class:DepthCamModule +createMatDepth modules/DepthCamModule.cpp /^bool DepthCamModule::createMatDepth(){$/;" f class:DepthCamModule +createMatDepth modules/DepthCamModule.hpp /^ bool createMatDepth();$/;" p class:DepthCamModule +createMatDepthAndColor modules/DepthCamModule.cpp /^bool DepthCamModule::createMatDepthAndColor(){$/;" f class:DepthCamModule +createMatDepthAndColor modules/DepthCamModule.hpp /^ bool createMatDepthAndColor();$/;" p class:DepthCamModule +createModule Reveal.cpp /^Module* Reveal::createModule(const std::string& typeStr) {$/;" f class:Reveal +createModule Reveal.hpp /^ Module* createModule(const std::string& typeStr);$/;" p class:Reveal +createProgram Reveal.cpp /^GLuint Reveal::createProgram(const char* vertSource, const char* fragSource) {$/;" f class:Reveal +createProgram Reveal.hpp /^ GLuint createProgram(const char* vertSource, const char* fragSource);$/;" p class:Reveal +createRTT modules/ProjectorModule.cpp /^void ProjectorModule::createRTT(GLuint& tex, GLuint& fbo) {$/;" f class:ProjectorModule +createRTT modules/ProjectorModule.hpp /^ void createRTT(GLuint& tex, GLuint& fbo);$/;" p class:ProjectorModule +cstr_compare osc/oscPack/osc/MessageMappingOscPacketListener.h /^ struct cstr_compare{$/;" s class:osc::MessageMappingOscPacketListener +cursCallback modules/DepthCamModule.hpp /^ static void cursCallback(Module* mod, const std::vector<float>& vals) {}$/;" f class:DepthCamModule +data osc/oscPack/osc/OscTypes.h /^ const void* data;$/;" m struct:osc::Blob +data_ osc/oscPack/osc/OscOutboundPacketStream.h /^ char *data_;$/;" m class:osc::OutboundPacketStream +deactivateColor modules/DepthCamModule.cpp /^void DepthCamModule::deactivateColor() {$/;" f class:DepthCamModule +deactivateColor modules/DepthCamModule.hpp /^ void deactivateColor();$/;" p class:DepthCamModule +debugMarkers modules/DepthCamModule.cpp /^void DepthCamModule::debugMarkers(const bool& val) {$/;" f class:DepthCamModule +debugMarkers modules/DepthCamModule.hpp /^ void debugMarkers(const bool& val);$/;" p class:DepthCamModule +debugMarkersCallback modules/DepthCamModule.hpp /^ static void debugMarkersCallback(Module* mod,$/;" f class:DepthCamModule +deleteCallback modules/SceneGroupModule.hpp /^ static void deleteCallback(Module* mod) {$/;" f class:SceneGroupModule +deleteChildren modules/GroupModule.cpp /^void GroupModule::deleteChildren() {$/;" f class:GroupModule +deleteChildren modules/GroupModule.hpp /^ void deleteChildren();$/;" p class:GroupModule +deleteListener Reveal.cpp /^void Reveal::deleteListener(Listener* lis) {$/;" f class:Reveal +deleteListener Reveal.hpp /^ void deleteListener(Listener*);$/;" p class:Reveal +deleteListener modules/Listener.cpp /^void Listener::deleteListener() {$/;" f class:Listener +deleteListener modules/Listener.hpp /^ void deleteListener();$/;" p class:Listener +deleteModule Reveal.cpp /^void Reveal::deleteModule(Module* mod) {$/;" f class:Reveal +deleteModule Reveal.hpp /^ void deleteModule(Module*);$/;" p class:Reveal +deleteModule modules/DepthCamModule.cpp /^void DepthCamModule::deleteModule() {$/;" f class:DepthCamModule +deleteModule modules/DepthCamModule.hpp /^ void deleteModule();$/;" p class:DepthCamModule +deleteModule modules/DepthGroupModule.cpp /^void DepthGroupModule::deleteModule() {$/;" f class:DepthGroupModule +deleteModule modules/DepthGroupModule.hpp /^ void deleteModule();$/;" p class:DepthGroupModule +deleteModule modules/DepthModule.cpp /^void DepthModule::deleteModule() {$/;" f class:DepthModule +deleteModule modules/DepthModule.hpp /^ void deleteModule();$/;" p class:DepthModule +deleteModule modules/GeomModule.cpp /^void GeomModule::deleteModule() {$/;" f class:GeomModule +deleteModule modules/GeomModule.hpp /^ void deleteModule();$/;" p class:GeomModule +deleteModule modules/GroupModule.cpp /^void GroupModule::deleteModule() {$/;" f class:GroupModule +deleteModule modules/GroupModule.hpp /^ void deleteModule();$/;" p class:GroupModule +deleteModule modules/Module.cpp /^void Module::deleteModule() {$/;" f class:Module +deleteModule modules/Module.hpp /^ virtual void deleteModule();$/;" p class:Module +deleteModule modules/ProjectorModule.cpp /^void ProjectorModule::deleteModule() {$/;" f class:ProjectorModule +deleteModule modules/ProjectorModule.hpp /^ void deleteModule();$/;" p class:ProjectorModule +deleteModule modules/RevealedModule.cpp /^void RevealedModule::deleteModule() {$/;" f class:RevealedModule +deleteModule modules/RevealedModule.hpp /^ void deleteModule();$/;" p class:RevealedModule +delimitation modules/DepthCamModule.cpp /^void DepthCamModule::delimitation(cv::Mat& img) {$/;" f class:DepthCamModule +delimitation modules/DepthCamModule.hpp /^ void delimitation(cv::Mat& img);$/;" p class:DepthCamModule +detachProj modules/DepthCamModule.cpp /^void DepthCamModule::detachProj(ProjectorModule* proj) {$/;" f class:DepthCamModule +detachProj modules/DepthCamModule.hpp /^ void detachProj(ProjectorModule*);$/;" p class:DepthCamModule +detectMarkers modules/DepthCamModule.cpp /^void DepthCamModule::detectMarkers() {$/;" f class:DepthCamModule +detectMarkers modules/DepthCamModule.hpp /^ void detectMarkers();$/;" p class:DepthCamModule +detected modules/DepthCamModule.hpp /^ bool detected;$/;" m struct:s_markerAndTime +detection modules/DepthCamModule.hpp /^ time_t detection;$/;" m struct:s_markerAndTime +deviceCallback modules/DepthCamModule.hpp /^ static void deviceCallback(Module* mod,$/;" f class:DepthCamModule +dimensionsCallback modules/RevealedTextModule.hpp /^ static void dimensionsCallback(Module* mod, $/;" f class:RevealedTextModule +dimensionsCallback modules/ShapeModule.hpp /^ static void dimensionsCallback(Module* mod, $/;" f class:ShapeModule +displayAttributes gui/MainWindow.cpp /^void MainWindow::displayAttributes(ModuleWidget* mod) {$/;" f class:MainWindow +displayAttributes gui/MainWindow.hpp /^ void displayAttributes(ModuleWidget*);$/;" p class:MainWindow +draw geoms/Geometry.cpp /^void Geometry::draw(const int& contextID,$/;" f class:Geometry +draw geoms/Geometry.hpp /^ virtual void draw(const int& contextID,$/;" p class:Geometry +draw modules/DepthCamModule.cpp /^void DepthCamModule::draw(const int& contextID,$/;" f class:DepthCamModule +draw modules/DepthCamModule.hpp /^ virtual void draw(const int& contextID,$/;" p class:DepthCamModule +draw modules/DepthModule.cpp /^void DepthModule::draw(const int& contextID,$/;" f class:DepthModule +draw modules/DepthModule.hpp /^ virtual void draw(const int& contextID,$/;" p class:DepthModule +draw modules/GeomModule.cpp /^void GeomModule::draw(const int& contextID,$/;" f class:GeomModule +draw modules/GeomModule.hpp /^ virtual void draw(const int& contextID,$/;" p class:GeomModule +draw modules/GroupModule.cpp /^void GroupModule::draw() {$/;" f class:GroupModule +draw modules/GroupModule.hpp /^ virtual void draw();$/;" p class:GroupModule +draw modules/Module.hpp /^ virtual void draw(){}$/;" f class:Module +draw modules/PreviewModule.cpp /^void PreviewModule::draw() {$/;" f class:PreviewModule +draw modules/PreviewModule.hpp /^ virtual void draw();$/;" p class:PreviewModule +draw modules/ProjectorModule.cpp /^void ProjectorModule::draw() {$/;" f class:ProjectorModule +draw modules/ProjectorModule.hpp /^ virtual void draw();$/;" p class:ProjectorModule +draw modules/RevealedCutModule.cpp /^void RevealedCutModule::draw(const int& contextID, $/;" f class:RevealedCutModule +draw modules/RevealedCutModule.hpp /^ void draw(const int& contextID,$/;" p class:RevealedCutModule +draw modules/RevealedModelModule.cpp /^void RevealedModelModule::draw(const int& contextID, $/;" f class:RevealedModelModule +draw modules/RevealedModelModule.hpp /^ void draw(const int& contextID,$/;" p class:RevealedModelModule +draw modules/RevealedModule.cpp /^void RevealedModule::draw(const int& contextID,$/;" f class:RevealedModule +draw modules/RevealedModule.hpp /^ void draw(const int& contextID,$/;" p class:RevealedModule +draw modules/SpaceModule.cpp /^void SpaceModule::draw() {$/;" f class:SpaceModule +draw modules/SpaceModule.hpp /^ virtual void draw();$/;" p class:SpaceModule +drawDelaunay modules/DepthCamModule.cpp /^void DepthCamModule::drawDelaunay(cv::Mat& img, cv::Subdiv2D& subdiv, cv::Scalar delaunayColor ){$/;" f class:DepthCamModule +drawDelaunay modules/DepthCamModule.hpp /^ void drawDelaunay(cv::Mat& img, cv::Subdiv2D& subdiv, $/;" p class:DepthCamModule +drawDirect geoms/Geometry.cpp /^void Geometry::drawDirect(const int& contextID) {$/;" f class:Geometry +drawDirect geoms/Geometry.hpp /^ virtual void drawDirect(const int& contextID);$/;" p class:Geometry +drawVoronoi modules/DepthCamModule.cpp /^void DepthCamModule::drawVoronoi( cv::Mat& img, cv::Subdiv2D& subdiv) {$/;" f class:DepthCamModule +drawVoronoi modules/DepthCamModule.hpp /^ void drawVoronoi(cv::Mat& img, cv::Subdiv2D& subdiv);$/;" p class:DepthCamModule +draw_point modules/DepthCamModule.cpp /^void DepthCamModule::draw_point(cv::Mat& img, cv::Point2f fp){$/;" f class:DepthCamModule +draw_point modules/DepthCamModule.hpp /^ void draw_point(cv::Mat& img, cv::Point2f fp);$/;" p class:DepthCamModule +edgesCallback modules/RevealedPathModule.hpp /^ static void edgesCallback(Module* mod, $/;" f class:RevealedPathModule +editAttributes modules/Module.hpp /^ inline std::vector<Attribute*>& editAttributes() { $/;" f class:Module +editCompoSizes geoms/Geometry.hpp /^ std::vector<int>& editCompoSizes(){return m_compoSizes;}$/;" f class:Geometry +editIndexBufferData geoms/Geometry.hpp /^ std::vector<GLuint>& editIndexBufferData(){return m_indexBufferData;}$/;" f class:Geometry +editListenerType modules/Listener.hpp /^ inline std::string& editListenerType(){return m_listenerType;}$/;" f class:Listener +editListeners modules/Attribute.hpp /^ inline std::vector<Listener*>& editListeners(){return m_listeners;}$/;" f class:Attribute +editParameters modules/Listener.hpp /^ inline std::vector<std::string>& editParameters(){return m_parameters;}$/;" f class:Listener +editPos modules/RevealedPathModule.hpp /^ inline glm::vec4& editPos(){return m_point;}$/;" f class:PathPoint +editRegisteredOutputDepthCams Reveal.hpp /^ inline std::vector<DepthCamModule*>& editRegisteredOutputDepthCams() {$/;" f class:Reveal +editRegisteredOutputRevealed Reveal.hpp /^ inline std::vector<RevealedModule*>& editRegisteredOutputRevealed() {$/;" f class:Reveal +editStringValuesChoices modules/Attribute.hpp /^ editStringValuesChoices() {$/;" f class:Attribute +editValueLabels modules/Attribute.hpp /^ inline std::vector<std::string>& editValueLabels() {$/;" f class:Attribute +editValuesMax modules/Attribute.hpp /^ inline std::vector<float>& editValuesMax() {return m_valuesMax;}$/;" f class:Attribute +editValuesMin modules/Attribute.hpp /^ inline std::vector<float>& editValuesMin() {return m_valuesMin;}$/;" f class:Attribute +editVertexBufferData geoms/Geometry.hpp /^ std::vector<GLfloat>& editVertexBufferData(){return m_vertexBufferData;}$/;" f class:Geometry +editWindowList modules/RevealedCutModule.hpp /^ std::vector<CutWindow*>& editWindowList(){return m_windowList;}$/;" f class:CutWindowsManager +elementCount_ osc/oscPack/osc/OscReceivedElements.h /^ uint32 elementCount_;$/;" m class:osc::ReceivedBundle +elementSizePtr_ osc/oscPack/osc/OscOutboundPacketStream.h /^ uint32 *elementSizePtr_;$/;" m class:osc::OutboundPacketStream +end_ osc/oscPack/osc/OscOutboundPacketStream.h /^ char *end_;$/;" m class:osc::OutboundPacketStream +end_ osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentIterator p_, end_;$/;" m class:osc::ReceivedMessageArgumentStream +end_ osc/oscPack/osc/OscReceivedElements.h /^ const char *end_;$/;" m class:osc::ReceivedBundle +extractOutputValue modules/ProjectorModule.cpp /^void ProjectorModule::extractOutputValue(const unsigned int& offset,$/;" f class:ProjectorModule +extractOutputValue modules/ProjectorModule.hpp /^ void extractOutputValue(const unsigned int& offset, $/;" p class:ProjectorModule +eyePositionCallback modules/PreviewModule.hpp /^ static void eyePositionCallback(Module* mod, $/;" f class:PreviewModule +fillGroupWithAttributes gui/ModuleWidget.cpp /^void ModuleWidget::fillGroupWithAttributes(Fl_Pack* group) {$/;" f class:ModuleWidget +fillGroupWithAttributes gui/ModuleWidget.hpp /^ void fillGroupWithAttributes(Fl_Pack*);$/;" p class:ModuleWidget +filterCallback modules/DepthCamModule.hpp /^ static void filterCallback(Module* mod,$/;" f class:DepthCamModule +filterMarkers modules/DepthCamModule.cpp /^void DepthCamModule::filterMarkers(vector<vector<cv::Point2f> >& cor,$/;" f class:DepthCamModule +filterMarkers modules/DepthCamModule.hpp /^ void filterMarkers(std::vector<std::vector<cv::Point2f> >& cor,$/;" p class:DepthCamModule +findAttribute Reveal.cpp /^Attribute* Reveal::findAttribute(const std::string& fullName) {$/;" f class:Reveal +findAttribute Reveal.hpp /^ Attribute* findAttribute(const std::string& fullName);$/;" p class:Reveal +findModule Reveal.cpp /^Module* Reveal::findModule(const std::string& fullName) {$/;" f class:Reveal +findModule Reveal.hpp /^ Module* findModule(const std::string& fullName);$/;" p class:Reveal +fontSizeCallback modules/RevealedTextModule.hpp /^ static void fontSizeCallback(Module* mod, $/;" f class:RevealedTextModule +framebufferSizeCallback modules/ProjectorModule.hpp /^ static void framebufferSizeCallback(GLFWwindow* win, int w, int h) {$/;" f class:ProjectorModule +fullscreenMonitor modules/ProjectorModule.cpp /^void ProjectorModule::fullscreenMonitor(const std::string& monitorName) {$/;" f class:ProjectorModule +fullscreenMonitor modules/ProjectorModule.hpp /^ void fullscreenMonitor(const std::string& monitor);$/;" p class:ProjectorModule +fullscreenMonitorCallback modules/ProjectorModule.hpp /^ static void fullscreenMonitorCallback(Module* mod, $/;" f class:ProjectorModule +function_map_type osc/oscPack/osc/MessageMappingOscPacketListener.h /^ typedef std::map<const char*, function_type, cstr_compare> function_map_type;$/;" t class:osc::MessageMappingOscPacketListener +function_type osc/oscPack/osc/MessageMappingOscPacketListener.h /^ typedef void (T::*function_type)(const osc::ReceivedMessage&, const IpEndpointName&);$/;" t class:osc::MessageMappingOscPacketListener +functions_ osc/oscPack/osc/MessageMappingOscPacketListener.h /^ function_map_type functions_;$/;" m class:osc::MessageMappingOscPacketListener +generateLayers modules/RevealedModelModule.cpp /^void RevealedModelModule::generateLayers() {$/;" f class:RevealedModelModule +generateLayers modules/RevealedModelModule.hpp /^ void generateLayers();$/;" p class:RevealedModelModule +generateLayersCallback modules/RevealedModelModule.hpp /^ static void generateLayersCallback(Module* mod) {$/;" f class:RevealedModelModule +generateReduction modules/RevealedModule.cpp /^void RevealedModule::generateReduction() {$/;" f class:RevealedModule +generateReduction modules/RevealedModule.hpp /^ virtual void generateReduction();$/;" p class:RevealedModule +generateReductionCallback modules/RevealedModule.hpp /^ static void generateReductionCallback(Module* mod) {$/;" f class:RevealedModule +getAbsPathFromRev modules/Attribute.cpp /^void Attribute::getAbsPathFromRev(const string& rel, $/;" f class:Attribute +getAbsPathFromRev modules/Attribute.hpp /^ void getAbsPathFromRev(const std::string& rel, $/;" p class:Attribute +getAccessibility modules/Attribute.hpp /^ ACCESSIBILITY getAccessibility(){return m_accessibility;}$/;" f class:Attribute +getAttribute modules/Module.hpp /^ inline Attribute* getAttribute(const std::string& attr) { $/;" f class:Module +getAttribute modules/Module.hpp /^ inline Attribute* getAttribute(const unsigned int& attr) { $/;" f class:Module +getBool modules/Attribute.hpp /^ bool getBool(const unsigned int& i) {return m_boolValues[i];}$/;" f class:Attribute +getChildID modules/Module.hpp /^ const unsigned int& getChildID(){return m_childID;}$/;" f class:Module +getColorFrame modules/DepthCamModule.hpp /^ inline openni::VideoFrameRef getColorFrame(){return m_colorFrame;}$/;" f class:DepthCamModule +getContextHandlerID modules/ContextHandler.hpp /^ const int& getContextHandlerID(){return m_contextHandlerID;}$/;" f class:ContextHandler +getCurrentFile Reveal.hpp /^ const std::string& getCurrentFile(){return m_currentFile;}$/;" f class:Reveal +getDepth modules/Module.hpp /^ inline const unsigned int& getDepth(){return m_depth;}$/;" f class:Module +getDepthCamModule modules/SpaceModule.cpp /^DepthCamModule* SpaceModule::getDepthCamModule(const std::string& name) {$/;" f class:SpaceModule +getDepthCamModule modules/SpaceModule.hpp /^ DepthCamModule* getDepthCamModule(const std::string& name);$/;" p class:SpaceModule +getDepthCamModule modules/SpaceModule.hpp /^ inline DepthCamModule* getDepthCamModule(const unsigned int& mod) {$/;" f class:SpaceModule +getDepthFrame modules/DepthCamModule.hpp /^ inline openni::VideoFrameRef getDepthFrame(){return m_depthFrame;}$/;" f class:DepthCamModule +getDepthID modules/DepthModule.hpp /^ const unsigned int& getDepthID(){return m_depthID;}$/;" f class:DepthModule +getDepthModuleFromID modules/SpaceModule.hpp /^ DepthModule* getDepthModuleFromID(const unsigned int& id){ $/;" f class:SpaceModule +getDepthStream modules/DepthCamModule.hpp /^ inline openni::VideoStream& getDepthStream(){return m_depth;}$/;" f class:DepthCamModule +getDeviceID modules/DepthCamModule.hpp /^ inline const std::string& getDeviceID(){return m_deviceID;}$/;" f class:DepthCamModule +getFile modules/Attribute.hpp /^ const std::string& getFile() {return m_stringValues[0];}$/;" f class:Attribute +getFloat modules/Attribute.hpp /^ const float& getFloat(const unsigned int& f) {return m_floatValues[f];}$/;" f class:Attribute +getFloats modules/Attribute.hpp /^ const std::vector<float>& getFloats(){return m_floatValues;}$/;" f class:Attribute +getFrames modules/DepthCamModule.cpp /^bool DepthCamModule::getFrames() {$/;" f class:DepthCamModule +getFrames modules/DepthCamModule.hpp /^ bool getFrames();$/;" p class:DepthCamModule +getFullName modules/Attribute.hpp /^ inline const std::string& getFullName(){return m_fullName;}$/;" f class:Attribute +getFullName modules/Module.hpp /^ inline const std::string& getFullName(){return m_fullName;}$/;" f class:Module +getGeom Reveal.hpp /^ Geometry* getGeom(const GEOM_ID& geomStr) { $/;" f class:Reveal +getGeom modules/SpaceModule.hpp /^ Geometry* getGeom(const Reveal::GEOM_ID& geomStr) { $/;" f class:SpaceModule +getGeomID geoms/Geometry.hpp /^ inline const Reveal::GEOM_ID& getGeomID() {return m_geomID;}$/;" f class:Geometry +getGeomID modules/GeomModule.hpp /^ virtual const unsigned int& getGeomID(){return m_geomID;}$/;" f class:GeomModule +getGeoms Reveal.hpp /^ const std::vector<Geometry*>& getGeoms(){return m_geoms;}$/;" f class:Reveal +getGeoms modules/SpaceModule.hpp /^ const std::vector<Geometry*>& getGeoms(){return m_geoms;}$/;" f class:SpaceModule +getHeight modules/RevealedCutModule.hpp /^ const int& getHeight(){return m_height;} $/;" f class:CutWindow +getHorizontalFOV modules/DepthCamModule.hpp /^ inline double& getHorizontalFOV(){return m_horizontalFOV;}$/;" f class:DepthCamModule +getID modules/Listener.hpp /^ inline const int& getID(){return m_listenerID;}$/;" f class:Listener +getInstance Reveal.cpp /^Reveal* Reveal::getInstance() {$/;" f class:Reveal +getInstance Reveal.hpp /^ static Reveal* getInstance();$/;" p class:Reveal +getInstance gui/MainWindow.cpp /^MainWindow* MainWindow::getInstance() {$/;" f class:MainWindow +getInstance gui/MainWindow.hpp /^ static MainWindow* getInstance();$/;" p class:MainWindow +getInstance modules/RevealedCutModule.cpp /^CutWindowsManager* CutWindowsManager::getInstance() {$/;" f class:CutWindowsManager +getInstance modules/RevealedCutModule.hpp /^ static CutWindowsManager* getInstance();$/;" p class:CutWindowsManager +getInstance osc/OscManager.cpp /^OscManager* OscManager::getInstance() {$/;" f class:OscManager +getInstance osc/OscManager.hpp /^ static OscManager* getInstance();$/;" p class:OscManager +getInt modules/Attribute.hpp /^ const int& getInt(const unsigned int& i) {return m_intValues[i];}$/;" f class:Attribute +getListenerType modules/Listener.hpp /^ inline const std::string& getListenerType(){return m_listenerType;}$/;" f class:Listener +getListenersGroup gui/MainWindow.hpp /^ inline Fl_Pack* getListenersGroup(){return m_listeners;}$/;" f class:MainWindow +getMaxNbDepthCams Reveal.hpp /^ inline const int& getMaxNbDepthCams(){return m_maxNbDepthCams;}$/;" f class:Reveal +getMaxNbRevealed Reveal.hpp /^ inline const int& getMaxNbRevealed(){return m_maxNbRevealed;}$/;" f class:Reveal +getModelMat modules/Module.hpp /^ const glm::mat4& getModelMat(){return m_modelMat;}$/;" f class:Module +getModule gui/ModuleWidget.hpp /^ inline Module* getModule(){return m_module;}$/;" f class:ModuleWidget +getModuleListObsID Reveal.hpp /^ const unsigned int& getModuleListObsID(){return m_moduleListObsID;}$/;" f class:ModuleListObserver +getModules geoms/Geometry.hpp /^ inline const std::vector<GeomModule*>& getModules(){return m_modules;}$/;" f class:Geometry +getName modules/Attribute.hpp /^ inline const std::string& getName(){return m_name;}$/;" f class:Attribute +getName modules/Module.hpp /^ inline const std::string& getName(){return m_name;}$/;" f class:Module +getName modules/RevealedCutModule.hpp /^ const std::string& getName(){return m_name;}$/;" f class:CutWindow +getNbAttributes modules/Module.hpp /^ inline unsigned int getNbAttributes(){return m_attributesVec.size();}$/;" f class:Module +getNbDepthModulesFromID modules/SpaceModule.hpp /^ unsigned int getNbDepthModulesFromID(){return m_depthIDsModules.size();}$/;" f class:SpaceModule +getNbRevealed Reveal.hpp /^ unsigned int getNbRevealed(){return m_revealedVec.size();}$/;" f class:Reveal +getNbSubDepthIDs modules/DepthCamModule.hpp /^ inline virtual int getNbSubDepthIDs(){return m_maxNbMarkers;}$/;" f class:DepthCamModule +getNbSubDepthIDs modules/DepthModule.hpp /^ inline virtual int getNbSubDepthIDs(){return 1;}$/;" f class:DepthModule +getNbValues modules/Attribute.hpp /^ inline const unsigned int& getNbValues(){return m_nbValues;}$/;" f class:Attribute +getNbWindows modules/RevealedCutModule.hpp /^ int getNbWindows(){return m_windowList.size();}$/;" f class:CutWindowsManager +getPos modules/RevealedPathModule.hpp /^ inline const glm::vec4& getPos(){return m_point;}$/;" f class:PathPoint +getPreviewWindow Reveal.cpp /^GLFWwindow* Reveal::getPreviewWindow() {$/;" f class:Reveal +getPreviewWindow Reveal.hpp /^ GLFWwindow* getPreviewWindow();$/;" p class:Reveal +getProjID modules/ProjectorModule.hpp /^ inline const int& getProjID(){return m_projID;}$/;" f class:ProjectorModule +getRelPathToRev modules/Attribute.cpp /^void Attribute::getRelPathToRev(const string& abs, $/;" f class:Attribute +getRelPathToRev modules/Attribute.hpp /^ void getRelPathToRev(const std::string& abs, $/;" p class:Attribute +getRevID modules/RevealedModule.hpp /^ inline const unsigned int& getRevID(){return m_revID;}$/;" f class:RevealedModule +getRevealedModule Reveal.hpp /^ RevealedModule* getRevealedModule(const unsigned int& s) { $/;" f class:Reveal +getString modules/Attribute.hpp /^ const std::string& getString(const unsigned int& s) { $/;" f class:Attribute +getStringValuesChoices modules/Attribute.hpp /^ getStringValuesChoices() {$/;" f class:Attribute +getSubTree modules/GroupModule.cpp /^void GroupModule::getSubTree(std::vector<Module*>& children) {$/;" f class:GroupModule +getSubTree modules/GroupModule.hpp /^ virtual void getSubTree(std::vector<Module*>& children); $/;" p class:GroupModule +getSubTree modules/Module.hpp /^ virtual void getSubTree(std::vector<Module*>& children) {$/;" f class:Module +getType modules/Attribute.hpp /^ inline const TYPE& getType(){return m_type;}$/;" f class:Attribute +getType modules/Module.hpp /^ inline const std::string& getType(){return m_type;}$/;" f class:Module +getUpID modules/Module.hpp /^ inline const int& getUpID(){return m_upID;}$/;" f class:Module +getValueLabels modules/Attribute.hpp /^ inline const std::vector<std::string>& getValueLabels() {$/;" f class:Attribute +getValuesMax modules/Attribute.hpp /^ inline const std::vector<float>& getValuesMax() {return m_valuesMax;}$/;" f class:Attribute +getValuesMin modules/Attribute.hpp /^ inline const std::vector<float>& getValuesMin() {return m_valuesMin;}$/;" f class:Attribute +getVerticalFOV modules/DepthCamModule.hpp /^ inline double& getVerticalFOV(){return m_verticalFOV;}$/;" f class:DepthCamModule +getVisibilityMask Reveal.cpp /^int Reveal::getVisibilityMask(const std::string& visibleFrom) {$/;" f class:Reveal +getVisibilityMask Reveal.hpp /^ int getVisibilityMask(const std::string& visibleFrom);$/;" p class:Reveal +getVisibilityMask modules/Module.hpp /^ inline const int& getVisibilityMask(){return m_visibilityMask;}$/;" f class:Module +getVisibleFromList modules/GroupModule.cpp /^void GroupModule::getVisibleFromList(std::vector<string>& modVec, $/;" f class:GroupModule +getVisibleFromList modules/GroupModule.hpp /^ virtual void getVisibleFromList(std::vector<std::string>& modVec, $/;" p class:GroupModule +getVisibleFromList modules/Module.hpp /^ virtual void getVisibleFromList(std::vector<std::string>& modVec, $/;" f class:Module +getVisibleFromList modules/SpaceModule.cpp /^void SpaceModule::getVisibleFromList(vector<string>& modVec, $/;" f class:SpaceModule +getVisibleFromList modules/SpaceModule.hpp /^ virtual void getVisibleFromList(std::vector<std::string>& modVec, $/;" p class:SpaceModule +getWidth modules/RevealedCutModule.hpp /^ const int& getWidth(){return m_width;} $/;" f class:CutWindow +getWinList modules/RevealedCutModule.cpp /^Window* CutWindowsManager::getWinList(Display* disp, unsigned long* len) {$/;" f class:CutWindowsManager +getWinList modules/RevealedCutModule.hpp /^ Window* getWinList(Display* disp, unsigned long* len);$/;" p class:CutWindowsManager +getWinName modules/RevealedCutModule.cpp /^char* CutWindowsManager::getWinName(Display* disp, Window win) {$/;" f class:CutWindowsManager +getWinName modules/RevealedCutModule.hpp /^ char* getWinName(Display* disp, Window);$/;" p class:CutWindowsManager +getWindow modules/PreviewModule.hpp /^ inline GLFWwindow* getWindow(){return m_previewWindow;}$/;" f class:PreviewModule +getWindow modules/RevealedCutModule.hpp /^ CutWindow* getWindow(const std::string& name) {$/;" f class:CutWindowsManager +globalFunction modules/DepthCamModule.cpp /^void DepthCamModule::globalFunction(cv::Mat &mat) {$/;" f class:DepthCamModule +globalFunction modules/DepthCamModule.hpp /^ void globalFunction(cv::Mat &mat);$/;" p class:DepthCamModule +gotAttributeListenersUpdate modules/DepthCamModule.cpp /^void DepthCamModule::gotAttributeListenersUpdate(Attribute* att) {$/;" f class:DepthCamModule +gotAttributeListenersUpdate modules/DepthCamModule.hpp /^ void gotAttributeListenersUpdate(Attribute*);$/;" p class:DepthCamModule +gotAttributeListenersUpdate modules/Module.hpp /^ virtual void gotAttributeListenersUpdate(Attribute*){}$/;" f class:Module +gotAttributeListenersUpdate modules/RevealedModelModule.hpp /^ void gotAttributeListenersUpdate(Attribute* att) { $/;" f class:RevealedModelModule +gotAttributeListenersUpdate modules/RevealedModule.cpp /^void RevealedModule::gotAttributeListenersUpdate(Attribute* att) {$/;" f class:RevealedModule +gotAttributeListenersUpdate modules/RevealedModule.hpp /^ void gotAttributeListenersUpdate(Attribute*);$/;" p class:RevealedModule +gotAttributeListenersUpdate modules/RevealedShapeModule.hpp /^ void gotAttributeListenersUpdate(Attribute* att) { $/;" f class:RevealedShapeModule +grabImage modules/RevealedCutModule.cpp /^uchar* CutWindow::grabImage() {$/;" f class:CutWindow +grabImage modules/RevealedCutModule.hpp /^ uchar* grabImage();$/;" p class:CutWindow +gradientTypeCallback modules/RevealedModule.hpp /^ static void gradientTypeCallback(Module* mod, $/;" f class:RevealedModule +handle gui/MainWindow.cpp /^int MainWindow::handle(int event) {$/;" f class:MainWindow +handle gui/MainWindow.hpp /^ int handle(int event);$/;" p class:MainWindow +hasTexCoords geoms/Geometry.hpp /^ void hasTexCoords(bool tc){m_hasTexCoords=tc;}$/;" f class:Geometry +hideListeners gui/MainWindow.cpp /^void MainWindow::hideListeners() {$/;" f class:MainWindow +hideListeners gui/MainWindow.hpp /^ void hideListeners();$/;" p class:MainWindow +hsv2rgb modules/RevealedModule.cpp /^void RevealedModule::hsv2rgb(const vector<float>& hsv, $/;" f class:RevealedModule +hsv2rgb modules/RevealedModule.hpp /^ void hsv2rgb(const std::vector<float>& hsv, $/;" p class:RevealedModule +id modules/DepthCamModule.hpp /^ int id;$/;" m struct:s_markerAndTime +idleFunc Reveal.cpp /^void idleFunc(void* data) {$/;" f +imageMarkersFolderCallback modules/DepthCamModule.hpp /^ static void imageMarkersFolderCallback(Module* mod, $/;" f class:DepthCamModule +impl_ osc/oscPack/ip/UdpSocket.h /^ Implementation *impl_;$/;" m class:SocketReceiveMultiplexer +impl_ osc/oscPack/ip/UdpSocket.h /^ Implementation *impl_;$/;" m class:UdpSocket +init Reveal.cpp /^void Reveal::init() {$/;" f class:Reveal +init Reveal.hpp /^ void init();$/;" p class:Reveal +init gui/MainWindow.cpp /^void MainWindow::init() {$/;" f class:MainWindow +init gui/MainWindow.hpp /^ void init();$/;" p class:MainWindow +init modules/DepthCamModule.cpp /^void ArucoTracker::init() {$/;" f class:ArucoTracker +init modules/DepthCamModule.cpp /^void ImageTracker::init() {$/;" f class:ImageTracker +init modules/DepthCamModule.hpp /^ virtual void init()=0;$/;" p class:Tracker +init modules/DepthCamModule.hpp /^ void init();$/;" p class:ArucoTracker +init modules/DepthCamModule.hpp /^ void init();$/;" p class:ImageTracker +init osc/OscManager.cpp /^void OscManager::init() {$/;" f class:OscManager +init osc/OscManager.hpp /^ void init();$/;" p class:OscManager +initBools modules/Attribute.hpp /^ void initBools(const std::vector<bool>& bools) {$/;" f class:Attribute +initCount_ osc/oscPack/ip/win32/NetworkingUtils.cpp /^static LONG initCount_ = 0;$/;" v file: +initFile modules/Attribute.hpp /^ void initFile(const std::string& f) {m_stringValues[0]=f;}$/;" f class:Attribute +initFloats modules/Attribute.hpp /^ void initFloats(const std::vector<float>& floats) {$/;" f class:Attribute +initGL modules/PreviewModule.cpp /^void PreviewModule::initGL() {$/;" f class:PreviewModule +initGL modules/PreviewModule.hpp /^ void initGL();$/;" p class:PreviewModule +initGL modules/ProjectorModule.cpp /^void ProjectorModule::initGL() {$/;" f class:ProjectorModule +initGL modules/ProjectorModule.hpp /^ void initGL();$/;" p class:ProjectorModule +initInts modules/Attribute.hpp /^ void initInts(const std::vector<int>& ints) {$/;" f class:Attribute +initPrograms Reveal.hpp /^ void initPrograms();$/;" p class:Reveal +initStrings modules/Attribute.hpp /^ void initStrings(const std::vector<std::string>& strings) {$/;" f class:Attribute +initialDelayMs osc/oscPack/ip/posix/UdpSocket.cpp /^ int initialDelayMs;$/;" m struct:AttachedTimerListener file: +initialDelayMs osc/oscPack/ip/win32/UdpSocket.cpp /^ int initialDelayMs;$/;" m struct:AttachedTimerListener file: +insideAxesCallback modules/RevealedModule.hpp /^ static void insideAxesCallback(Module* mod, $/;" f class:RevealedModule +insideCallback modules/RevealedModule.hpp /^ static void insideCallback(Module* mod, $/;" f class:RevealedModule +int32 osc/oscPack/osc/OscTypes.h /^typedef signed int int32;$/;" t namespace:osc +int32 osc/oscPack/osc/OscTypes.h /^typedef signed long int32;$/;" t namespace:osc +int64 osc/oscPack/osc/OscTypes.h /^typedef __int64 int64;$/;" t namespace:osc +isBound_ osc/oscPack/ip/posix/UdpSocket.cpp /^ bool isBound_;$/;" m class:UdpSocket::Implementation file: +isBound_ osc/oscPack/ip/win32/UdpSocket.cpp /^ bool isBound_;$/;" m class:UdpSocket::Implementation file: +isConnected_ osc/oscPack/ip/posix/UdpSocket.cpp /^ bool isConnected_;$/;" m class:UdpSocket::Implementation file: +isConnected_ osc/oscPack/ip/win32/UdpSocket.cpp /^ bool isConnected_;$/;" m class:UdpSocket::Implementation file: +isOpen modules/DepthCamModule.hpp /^ bool isOpen(){return m_open;}$/;" f class:DepthCamModule +isOutputActive modules/RevealedModule.hpp /^ inline bool isOutputActive(){return m_outputActive;}$/;" f class:RevealedModule +isVisible modules/Module.hpp /^ inline bool isVisible(){return m_visible && m_parentVisible;}$/;" f class:Module +jack_ringbuffer_create osc/ringbuffer.c /^ jack_ringbuffer_t *jack_ringbuffer_create(size_t sz);$/;" p file: +jack_ringbuffer_create osc/ringbuffer.c /^jack_ringbuffer_create (size_t sz)$/;" f +jack_ringbuffer_create osc/ringbuffer.h /^jack_ringbuffer_t *jack_ringbuffer_create(size_t sz);$/;" p +jack_ringbuffer_data_t osc/ringbuffer.c /^jack_ringbuffer_data_t ;$/;" t typeref:struct:__anon6 file: +jack_ringbuffer_data_t osc/ringbuffer.h /^jack_ringbuffer_data_t ;$/;" t typeref:struct:__anon1 +jack_ringbuffer_free osc/ringbuffer.c /^ void jack_ringbuffer_free(jack_ringbuffer_t *rb);$/;" p file: +jack_ringbuffer_free osc/ringbuffer.c /^jack_ringbuffer_free (jack_ringbuffer_t * rb)$/;" f +jack_ringbuffer_free osc/ringbuffer.h /^void jack_ringbuffer_free(jack_ringbuffer_t *rb);$/;" p +jack_ringbuffer_get_read_vector osc/ringbuffer.c /^ void jack_ringbuffer_get_read_vector(const jack_ringbuffer_t *rb,$/;" p file: +jack_ringbuffer_get_read_vector osc/ringbuffer.c /^jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb,$/;" f +jack_ringbuffer_get_read_vector osc/ringbuffer.h /^void jack_ringbuffer_get_read_vector(const jack_ringbuffer_t *rb,$/;" p +jack_ringbuffer_get_write_vector osc/ringbuffer.c /^ void jack_ringbuffer_get_write_vector(const jack_ringbuffer_t *rb,$/;" p file: +jack_ringbuffer_get_write_vector osc/ringbuffer.c /^jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb,$/;" f +jack_ringbuffer_get_write_vector osc/ringbuffer.h /^void jack_ringbuffer_get_write_vector(const jack_ringbuffer_t *rb,$/;" p +jack_ringbuffer_mlock osc/ringbuffer.c /^ int jack_ringbuffer_mlock(jack_ringbuffer_t *rb);$/;" p file: +jack_ringbuffer_mlock osc/ringbuffer.c /^jack_ringbuffer_mlock (jack_ringbuffer_t * rb)$/;" f +jack_ringbuffer_mlock osc/ringbuffer.h /^int jack_ringbuffer_mlock(jack_ringbuffer_t *rb);$/;" p +jack_ringbuffer_peek osc/ringbuffer.c /^ size_t jack_ringbuffer_peek(jack_ringbuffer_t *rb, char *dest, size_t cnt);$/;" p file: +jack_ringbuffer_peek osc/ringbuffer.c /^jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt)$/;" f +jack_ringbuffer_peek osc/ringbuffer.h /^size_t jack_ringbuffer_peek(jack_ringbuffer_t *rb, char *dest, size_t cnt);$/;" p +jack_ringbuffer_read osc/ringbuffer.c /^ size_t jack_ringbuffer_read(jack_ringbuffer_t *rb, char *dest, size_t cnt);$/;" p file: +jack_ringbuffer_read osc/ringbuffer.c /^jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt)$/;" f +jack_ringbuffer_read osc/ringbuffer.h /^size_t jack_ringbuffer_read(jack_ringbuffer_t *rb, char *dest, size_t cnt);$/;" p +jack_ringbuffer_read_advance osc/ringbuffer.c /^ void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt);$/;" p file: +jack_ringbuffer_read_advance osc/ringbuffer.c /^jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt)$/;" f +jack_ringbuffer_read_advance osc/ringbuffer.h /^void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt);$/;" p +jack_ringbuffer_read_space osc/ringbuffer.c /^ size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb);$/;" p file: +jack_ringbuffer_read_space osc/ringbuffer.c /^jack_ringbuffer_read_space (const jack_ringbuffer_t * rb)$/;" f +jack_ringbuffer_read_space osc/ringbuffer.h /^size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb);$/;" p +jack_ringbuffer_reset osc/ringbuffer.c /^ void jack_ringbuffer_reset(jack_ringbuffer_t *rb);$/;" p file: +jack_ringbuffer_reset osc/ringbuffer.c /^jack_ringbuffer_reset (jack_ringbuffer_t * rb)$/;" f +jack_ringbuffer_reset osc/ringbuffer.h /^void jack_ringbuffer_reset(jack_ringbuffer_t *rb);$/;" p +jack_ringbuffer_reset_size osc/ringbuffer.c /^ void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz);$/;" p file: +jack_ringbuffer_reset_size osc/ringbuffer.c /^jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz)$/;" f +jack_ringbuffer_reset_size osc/ringbuffer.h /^void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz);$/;" p +jack_ringbuffer_t osc/ringbuffer.c /^jack_ringbuffer_t ;$/;" t typeref:struct:__anon7 file: +jack_ringbuffer_t osc/ringbuffer.h /^jack_ringbuffer_t ;$/;" t typeref:struct:__anon2 +jack_ringbuffer_write osc/ringbuffer.c /^ size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src,$/;" p file: +jack_ringbuffer_write osc/ringbuffer.c /^jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt)$/;" f +jack_ringbuffer_write osc/ringbuffer.h /^size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src,$/;" p +jack_ringbuffer_write_advance osc/ringbuffer.c /^jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt)$/;" f +jack_ringbuffer_write_advance osc/ringbuffer.c /^void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt);$/;" p file: +jack_ringbuffer_write_advance osc/ringbuffer.h /^void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt);$/;" p +jack_ringbuffer_write_space osc/ringbuffer.c /^jack_ringbuffer_write_space (const jack_ringbuffer_t * rb)$/;" f +jack_ringbuffer_write_space osc/ringbuffer.c /^size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb);$/;" p file: +jack_ringbuffer_write_space osc/ringbuffer.h /^size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb);$/;" p +jointly modules/DepthCamModule.cpp /^int DepthCamModule::jointly(vector<cv::Point2f> points, cv::Point2f pt){$/;" f class:DepthCamModule +jointly modules/DepthCamModule.hpp /^ int jointly(std::vector<cv::Point2f> points, cv::Point2f pt);$/;" p class:DepthCamModule +len osc/ringbuffer.c /^ size_t len;$/;" m struct:__anon6 file: +len osc/ringbuffer.h /^ size_t len;$/;" m struct:__anon1 +listModulesAndAttributes modules/GroupModule.cpp /^void GroupModule::listModulesAndAttributes(const std::string& parentName, $/;" f class:GroupModule +listModulesAndAttributes modules/GroupModule.hpp /^ void listModulesAndAttributes(const std::string& parentName, $/;" p class:GroupModule +listModulesAndAttributes modules/Module.cpp /^void Module::listModulesAndAttributes(const std::string& parentName, $/;" f class:Module +listModulesAndAttributes modules/Module.hpp /^ virtual void listModulesAndAttributes(const std::string& parentName, $/;" p class:Module +listener osc/oscPack/ip/posix/UdpSocket.cpp /^ TimerListener *listener;$/;" m struct:AttachedTimerListener file: +listener osc/oscPack/ip/win32/UdpSocket.cpp /^ TimerListener *listener;$/;" m struct:AttachedTimerListener file: +listener_ osc/oscPack/ip/UdpSocket.h /^ PacketListener *listener_;$/;" m class:UdpListeningReceiveSocket +load Reveal.cpp /^void Reveal::load(xmlNodePtr node) {$/;" f class:Reveal +load Reveal.hpp /^ virtual void load(xmlNodePtr);$/;" p class:Reveal +load modules/Attribute.cpp /^void Attribute::load(xmlNodePtr node) {$/;" f class:Attribute +load modules/Attribute.hpp /^ void load(xmlNodePtr node);$/;" p class:Attribute +load modules/GroupModule.cpp /^void GroupModule::load(xmlNodePtr node) {$/;" f class:GroupModule +load modules/GroupModule.hpp /^ virtual void load(xmlNodePtr node);$/;" p class:GroupModule +load modules/Listener.cpp /^void Listener::load(xmlNodePtr lisNode) {$/;" f class:Listener +load modules/Listener.hpp /^ virtual void load(xmlNodePtr node);$/;" p class:Listener +load modules/Module.cpp /^void Module::load(xmlNodePtr node) {$/;" f class:Module +load modules/Module.hpp /^ virtual void load(xmlNodePtr node);$/;" p class:Module +load modules/PreviewModule.cpp /^void PreviewModule::load(xmlNodePtr node) {$/;" f class:PreviewModule +load modules/PreviewModule.hpp /^ virtual void load(xmlNodePtr node);$/;" p class:PreviewModule +load modules/RevealedPathModule.cpp /^void RevealedPathModule::load(xmlNodePtr node) {$/;" f class:RevealedPathModule +load modules/RevealedPathModule.hpp /^ virtual void load(xmlNodePtr node);$/;" p class:RevealedPathModule +load modules/SpaceModule.cpp /^void SpacesModule::load(xmlNodePtr node) {$/;" f class:SpacesModule +load modules/SpaceModule.hpp /^ virtual void load(xmlNodePtr node);$/;" p class:SpacesModule +loadPnt modules/RevealedPathModule.cpp /^void PathPoint::loadPnt(xmlNodePtr node) {$/;" f class:PathPoint +loadPnt modules/RevealedPathModule.cpp /^void PathPointModule::loadPnt(xmlNodePtr node) {$/;" f class:PathPointModule +loadPnt modules/RevealedPathModule.hpp /^ virtual void loadPnt(xmlNodePtr node);$/;" p class:PathPoint +loadPnt modules/RevealedPathModule.hpp /^ virtual void loadPnt(xmlNodePtr node);$/;" p class:PathPointModule +lookAtCallback modules/PreviewModule.hpp /^ static void lookAtCallback(Module* mod, $/;" f class:PreviewModule +m_absPoint modules/RevealedPathModule.hpp /^ glm::vec4 m_absPoint;$/;" m class:PathPoint +m_accessibility modules/Attribute.hpp /^ ACCESSIBILITY m_accessibility;$/;" m class:Attribute +m_accumTimeDiff modules/RevealedModule.hpp /^ int m_accumTimeDiff;$/;" m class:RevealedLayer +m_actionCallback modules/Attribute.hpp /^ ActionCallback* m_actionCallback;$/;" m class:Attribute +m_active modules/PreviewModule.hpp /^ bool m_active;$/;" m class:PreviewModule +m_active modules/ProjectorModule.hpp /^ bool m_active;$/;" m class:ProjectorModule +m_addListenerBut gui/AttributeWidget.hpp /^ Fl_Button* m_addListenerBut;$/;" m class:AttributeWidget +m_adress osc/OscListener.hpp /^ std::string m_adress;$/;" m class:OscListener +m_adress osc/OscManager.hpp /^ std::string m_adress;$/;" m struct:OscStream +m_aliveMarkers modules/DepthCamModule.hpp /^ std::map<int, s_markerAndTime> m_aliveMarkers;$/;" m class:DepthCamModule +m_arucoTracker modules/DepthCamModule.hpp /^ ArucoTracker* m_arucoTracker;$/;" m class:DepthCamModule +m_attachedProjs modules/DepthCamModule.hpp /^ std::map<int, ProjectorModule*> m_attachedProjs;$/;" m class:DepthCamModule +m_attachedToCam modules/ProjectorModule.hpp /^ DepthCamModule* m_attachedToCam;$/;" m class:ProjectorModule +m_attribute gui/AttributeWidget.hpp /^ Attribute* m_attribute;$/;" m class:AttributeWidget +m_attribute modules/Listener.hpp /^ Attribute* m_attribute;$/;" m class:Listener +m_attributeWidget gui/GuiListener.hpp /^ AttributeWidget* m_attributeWidget;$/;" m class:GuiListener +m_attributes gui/MainWindow.hpp /^ Fl_Pack* m_attributes;$/;" m class:MainWindow +m_attributesDeleteVec Reveal.hpp /^ std::vector<Attribute*> m_attributesDeleteVec;$/;" m class:Reveal +m_attributesMap modules/Module.hpp /^ std::map<std::string, Attribute*> m_attributesMap;$/;" m class:Module +m_attributesVec modules/Module.hpp /^ std::vector<Attribute*> m_attributesVec;$/;" m class:Module +m_attributesWidth gui/MainWindow.hpp /^ int m_attributesWidth;$/;" m class:MainWindow +m_backImg modules/DepthCamModule.hpp /^ cv::Mat m_backImg;$/;" m class:DepthCamModule +m_backgroundActive modules/DepthCamModule.hpp /^ bool m_backgroundActive;$/;" m class:DepthCamModule +m_bbPnts modules/GeomModule.hpp /^ glm::vec3 m_bbPnts[2];$/;" m class:GeomModule +m_bboxLocalMin modules/GeomModule.hpp /^ std::map<unsigned int, glm::vec4> m_bboxLocalMin;$/;" m class:GeomModule +m_bboxLocalSizes modules/GeomModule.hpp /^ std::map<unsigned int, glm::vec4> m_bboxLocalSizes;$/;" m class:GeomModule +m_bboxMins modules/GeomModule.hpp /^ std::map<unsigned int, glm::vec4> m_bboxMins;$/;" m class:GeomModule +m_bboxRots modules/GeomModule.hpp /^ std::map<unsigned int, glm::mat4> m_bboxRots;$/;" m class:GeomModule +m_bboxSizes modules/GeomModule.hpp /^ std::map<unsigned int, glm::vec4> m_bboxSizes;$/;" m class:GeomModule +m_blueXmm modules/DepthCamModule.hpp /^ int m_blueXmm, m_blueYmm, m_blueZmm;$/;" m class:DepthCamModule +m_blueYmm modules/DepthCamModule.hpp /^ int m_blueXmm, m_blueYmm, m_blueZmm;$/;" m class:DepthCamModule +m_blueZmm modules/DepthCamModule.hpp /^ int m_blueXmm, m_blueYmm, m_blueZmm;$/;" m class:DepthCamModule +m_boolCallback modules/Attribute.hpp /^ BoolCallback* m_boolCallback;$/;" m class:Attribute +m_boolValues modules/Attribute.hpp /^ std::vector<bool> m_boolValues;$/;" m class:Attribute +m_boolValues osc/OscManager.hpp /^ std::vector<bool> m_boolValues;$/;" m struct:OscMessage +m_buffer osc/OscManager.hpp /^ char m_buffer[IP_MTU_SIZE];$/;" m class:OscManager +m_buffer osc/OscManager.hpp /^ char m_buffer[IP_MTU_SIZE];$/;" m struct:OscStream +m_bundleStarted osc/OscManager.hpp /^ bool m_bundleStarted;$/;" m struct:OscStream +m_button gui/AttributeWidget.hpp /^ Fl_Button* m_button;$/;" m class:AttributeWidget +m_calibGeom modules/ProjectorModule.hpp /^ QuadGeometry* m_calibGeom;$/;" m class:ProjectorModule +m_calibrated modules/ProjectorModule.hpp /^ bool m_calibrated;$/;" m class:ProjectorModule +m_calibrating modules/DepthCamModule.hpp /^ int m_calibrating;$/;" m class:DepthCamModule +m_calibrating modules/ProjectorModule.hpp /^ int m_calibrating;$/;" m class:ProjectorModule +m_calibrationCam modules/ProjectorModule.hpp /^ DepthCamModule* m_calibrationCam;$/;" m class:ProjectorModule +m_calibrationProj modules/DepthCamModule.hpp /^ ProjectorModule* m_calibrationProj;$/;" m class:DepthCamModule +m_calibrationStopped modules/DepthCamModule.hpp /^ bool m_calibrationStopped;$/;" m class:DepthCamModule +m_calibrationStopped modules/ProjectorModule.hpp /^ bool m_calibrationStopped;$/;" m class:ProjectorModule +m_camTexMap modules/DepthCamModule.hpp /^ std::map<int, GLuint> m_camTexMap;$/;" m class:DepthCamModule +m_camTexMap1 modules/DepthCamModule.hpp /^ std::map<int, GLuint> m_camTexMap1;$/;" m class:DepthCamModule +m_camTexMap2 modules/DepthCamModule.hpp /^ std::map<int, GLuint> m_camTexMap2;$/;" m class:DepthCamModule +m_camTexUpMap modules/DepthCamModule.hpp /^ std::map<int, bool> m_camTexUpMap;$/;" m class:DepthCamModule +m_capturedBackground modules/DepthCamModule.hpp /^ bool m_capturedBackground;$/;" m class:DepthCamModule +m_capturingBackground modules/DepthCamModule.hpp /^ int m_capturingBackground;$/;" m class:DepthCamModule +m_checks gui/AttributeWidget.hpp /^ std::vector<Fl_Toggle_Button*> m_checks;$/;" m class:AttributeWidget +m_childID modules/Module.hpp /^ unsigned int m_childID;$/;" m class:Module +m_children modules/GroupModule.hpp /^ std::vector<Module*> m_children;$/;" m class:GroupModule +m_childrenMap modules/GroupModule.hpp /^ std::map<unsigned int, Module*> m_childrenMap;$/;" m class:GroupModule +m_choices gui/AttributeWidget.hpp /^ std::vector<Fl_Choice*> m_choices;$/;" m class:AttributeWidget +m_color modules/DepthCamModule.hpp /^ openni::VideoStream m_depth, m_color;$/;" m class:DepthCamModule +m_color modules/RevealedModule.hpp /^ std::vector<float> m_color;$/;" m class:RevealedModule +m_colorActivated modules/DepthCamModule.hpp /^ bool m_colorActivated;$/;" m class:DepthCamModule +m_colorFrame modules/DepthCamModule.hpp /^ openni::VideoFrameRef m_colorFrame;$/;" m class:DepthCamModule +m_cols modules/DepthCamModule.hpp /^ std::vector<int> m_cols;$/;" m class:ImageTracker +m_compoLocalSizes modules/RevealedPathModule.hpp /^ std::map<unsigned int, glm::vec4> m_compoLocalSizes;$/;" m class:RevealedPathModule +m_compoRots modules/RevealedPathModule.hpp /^ std::map<unsigned int, glm::mat4> m_compoRots;$/;" m class:RevealedPathModule +m_compoSizes geoms/Geometry.hpp /^ std::vector<int> m_compoSizes;$/;" m class:Geometry +m_compoVertices modules/RevealedPathModule.hpp /^ std::map<unsigned int, std::vector<glm::vec4> > m_compoVertices;$/;" m class:RevealedPathModule +m_contextHandlerID modules/ContextHandler.hpp /^ int m_contextHandlerID;$/;" m class:ContextHandler +m_contextHandlers Reveal.hpp /^ std::map<unsigned int, ContextHandler*> m_contextHandlers;$/;" m class:Reveal +m_contextHandlersCounter Reveal.hpp /^ int m_contextHandlersCounter;$/;" m class:Reveal +m_contexts geoms/Geometry.hpp /^ std::map<int, ContextGeometry> m_contexts;$/;" m class:Geometry +m_contourThreshold modules/DepthCamModule.hpp /^ float m_contourThreshold;$/;" m class:DepthCamModule +m_coordImage modules/ModelModule.hpp /^ float* m_coordImage;$/;" m class:ModelModule +m_coordImage modules/RevealedCutModule.hpp /^ float* m_coordImage;$/;" m class:RevealedCutModule +m_coordsIDMap modules/RevealedModule.hpp /^ std::map<int, GLuint> m_coordsIDMap;$/;" m class:RevealedModule +m_coordsUpMap modules/RevealedModule.hpp /^ std::map<int, bool> m_coordsUpMap;$/;" m class:RevealedModule +m_current modules/RevealedModule.hpp /^ int m_current;$/;" m class:RevealedLayerAnim +m_currentFile Reveal.hpp /^ std::string m_currentFile;$/;" m class:Reveal +m_currentGeom modules/GeomModule.hpp /^ Geometry* m_currentGeom;$/;" m class:GeomModule +m_currentShape modules/ShapeModule.hpp /^ std::string m_currentShape;$/;" m class:ShapeModule +m_currentTracker modules/DepthCamModule.hpp /^ Tracker* m_currentTracker;$/;" m class:DepthCamModule +m_cursorValues modules/DepthCamModule.hpp /^ std::vector<float> m_cursorValues;$/;" m class:DepthCamModule +m_cutWin modules/RevealedCutModule.hpp /^ CutWindow* m_cutWin;$/;" m class:RevealedCutModule +m_debuggingMarkers modules/DepthCamModule.hpp /^ bool m_debuggingMarkers;$/;" m class:DepthCamModule +m_defaultDepthFrame modules/DepthCamModule.hpp /^ unsigned short *m_defaultDepthFrame;$/;" m class:DepthCamModule +m_defaultFps modules/DepthCamModule.hpp /^ uint16_t m_defaultWidth, m_defaultHeight, m_defaultFps;$/;" m class:DepthCamModule +m_defaultHeight modules/DepthCamModule.hpp /^ uint16_t m_defaultWidth, m_defaultHeight, m_defaultFps;$/;" m class:DepthCamModule +m_defaultImgData modules/RevealedCutModule.hpp /^ uchar* m_defaultImgData;$/;" m class:CutWindow +m_defaultWidth modules/DepthCamModule.hpp /^ uint16_t m_defaultWidth, m_defaultHeight, m_defaultFps;$/;" m class:DepthCamModule +m_depth modules/DepthCamModule.hpp /^ openni::VideoStream m_depth, m_color;$/;" m class:DepthCamModule +m_depth modules/Module.hpp /^ unsigned int m_depth;$/;" m class:Module +m_depthCamModules modules/SpaceModule.hpp /^ std::vector<DepthCamModule*> m_depthCamModules;$/;" m class:SpaceModule +m_depthFrame modules/DepthCamModule.hpp /^ openni::VideoFrameRef m_depthFrame;$/;" m class:DepthCamModule +m_depthID modules/DepthModule.hpp /^ unsigned int m_depthID;$/;" m class:DepthModule +m_depthIDsModules modules/SpaceModule.hpp /^ std::map<unsigned int, DepthModule*> m_depthIDsModules;$/;" m class:SpaceModule +m_depthImg modules/DepthCamModule.hpp /^ cv::Mat m_depthImg;$/;" m class:DepthCamModule +m_depthMeshModules modules/SpaceModule.hpp /^ std::vector<DepthMeshModule*> m_depthMeshModules;$/;" m class:SpaceModule +m_depthModsMap modules/RevealedModule.hpp /^ std::map<unsigned int, bool> m_depthModsMap;$/;" m class:RevealedModule +m_depthModules modules/SpaceModule.hpp /^ std::vector<DepthModule*> m_depthModules;$/;" m class:SpaceModule +m_depthShapeModules modules/SpaceModule.hpp /^ std::vector<DepthShapeModule*> m_depthShapeModules;$/;" m class:SpaceModule +m_depthType modules/DepthModule.hpp /^ int m_depthType;$/;" m class:DepthModule +m_descriptors modules/DepthCamModule.hpp /^ std::vector<cv::Mat> m_descriptors;$/;" m class:ImageTracker +m_destIndices modules/RevealedCutModule.hpp /^ std::vector<int> m_destIndices;$/;" m class:RevealedCutModule +m_detDepthImg modules/DepthCamModule.hpp /^ cv::Mat m_detDepthImg;$/;" m class:DepthCamModule +m_detMarkImg modules/DepthCamModule.hpp /^ cv::Mat m_detMarkImg;$/;" m class:DepthCamModule +m_detRgbImg modules/DepthCamModule.hpp /^ cv::Mat m_detRgbImg;$/;" m class:DepthCamModule +m_detectLock modules/DepthCamModule.hpp /^ std::mutex m_detectLock;$/;" m class:DepthCamModule +m_detectedMarkers modules/DepthCamModule.hpp /^ std::vector<s_markerAndTime> m_detectedMarkers;$/;" m class:DepthCamModule +m_detectingMarkers modules/DepthCamModule.hpp /^ bool m_detectingMarkers;$/;" m class:DepthCamModule +m_detector modules/DepthCamModule.hpp /^ cv::Ptr<cv::Feature2D> m_detector;$/;" m class:ImageTracker +m_device modules/DepthCamModule.hpp /^ openni::Device m_device;$/;" m class:DepthCamModule +m_deviceID modules/DepthCamModule.hpp /^ std::string m_deviceID;$/;" m class:DepthCamModule +m_dimensions modules/ShapeModule.hpp /^ glm::vec3 m_dimensions;$/;" m class:ShapeModule +m_disp modules/RevealedCutModule.hpp /^ Display* m_disp;$/;" m class:CutWindow +m_disp modules/RevealedCutModule.hpp /^ Display* m_disp;$/;" m class:CutWindowsManager +m_eyePos modules/PreviewModule.hpp /^ glm::vec3 m_eyePos;$/;" m class:PreviewModule +m_far modules/PreviewModule.hpp /^ float m_far;$/;" m class:PreviewModule +m_fileCallback modules/Attribute.hpp /^ FileCallback* m_fileCallback;$/;" m class:Attribute +m_fileName gui/MainWindow.hpp /^ std::string m_fileName;$/;" m class:MainWindow +m_fillingMarkers modules/DepthCamModule.hpp /^ bool m_fillingMarkers;$/;" m class:DepthCamModule +m_filter modules/DepthCamModule.hpp /^ bool m_filter;$/;" m class:DepthCamModule +m_filterCursorSize modules/DepthCamModule.hpp /^ float m_filterCursorSize;$/;" m class:DepthCamModule +m_filterCursorSums modules/DepthCamModule.hpp /^ std::vector<float> m_filterCursorSums;$/;" m class:DepthCamModule +m_filterCursorValues modules/DepthCamModule.hpp /^ std::vector<std::deque<float> > m_filterCursorValues;$/;" m class:DepthCamModule +m_finalCombin modules/DepthCamModule.hpp /^ cv::Mat m_finalCombin;$/;" m class:DepthCamModule +m_floatCallback modules/Attribute.hpp /^ FloatCallback* m_floatCallback;$/;" m class:Attribute +m_floatValues modules/Attribute.hpp /^ std::vector<float> m_floatValues;$/;" m class:Attribute +m_floatValues osc/OscManager.hpp /^ std::vector<float> m_floatValues;$/;" m struct:OscMessage +m_foundCorners modules/ProjectorModule.hpp /^ std::vector<cv::Point2f> m_foundCorners;$/;" m class:ProjectorModule +m_fps modules/DepthCamModule.hpp /^ uint16_t m_width, m_height, m_fps;$/;" m class:DepthCamModule +m_frame modules/RevealedModule.hpp /^ cv::Mat m_frame;$/;" m class:RevealedLayerVideo +m_fullAttributesMap Reveal.hpp /^ std::map<std::string, Attribute*> m_fullAttributesMap;$/;" m class:Reveal +m_fullName gui/AttributeWidget.hpp /^ std::string m_fullName;$/;" m class:AttributeWidget +m_fullName modules/Attribute.hpp /^ std::string m_fullName;$/;" m class:Attribute +m_fullName modules/Module.hpp /^ std::string m_fullName;$/;" m class:Module +m_generatedCorners modules/ProjectorModule.hpp /^ std::vector<cv::Point2f> m_generatedCorners;$/;" m class:ProjectorModule +m_geomID geoms/Geometry.hpp /^ Reveal::GEOM_ID m_geomID;$/;" m class:Geometry +m_geomID modules/GeomModule.hpp /^ unsigned int m_geomID;$/;" m class:GeomModule +m_geometries modules/PreviewModule.hpp /^ std::vector<Geometry*> m_geometries;$/;" m class:PreviewModule +m_geoms Reveal.hpp /^ std::vector<Geometry*> m_geoms;$/;" m class:Reveal +m_geoms modules/SpaceModule.hpp /^ std::vector<Geometry*> m_geoms;$/;" m class:SpaceModule +m_geomsMap Reveal.hpp /^ std::map<GEOM_ID, Geometry*> m_geomsMap;$/;" m class:Reveal +m_geomsMap modules/SpaceModule.hpp /^ std::map<Reveal::GEOM_ID, Geometry*> m_geomsMap;$/;" m class:SpaceModule +m_gotColor modules/DepthCamModule.hpp /^ bool m_gotDepth, m_gotColor;$/;" m class:DepthCamModule +m_gotDepth modules/DepthCamModule.hpp /^ bool m_gotDepth, m_gotColor;$/;" m class:DepthCamModule +m_grabbed modules/RevealedCutModule.hpp /^ bool m_grabbed;$/;" m class:CutWindow +m_gradientType modules/RevealedModule.hpp /^ int m_gradientType;$/;" m class:RevealedModule +m_gradientTypes modules/RevealedModule.hpp /^ std::vector<std::string> m_gradientTypes;$/;" m class:RevealedModule +m_greenXmm modules/DepthCamModule.hpp /^ int m_greenXmm, m_greenYmm, m_greenZmm;$/;" m class:DepthCamModule +m_greenYmm modules/DepthCamModule.hpp /^ int m_greenXmm, m_greenYmm, m_greenZmm;$/;" m class:DepthCamModule +m_greenZmm modules/DepthCamModule.hpp /^ int m_greenXmm, m_greenYmm, m_greenZmm;$/;" m class:DepthCamModule +m_guiListener gui/AttributeWidget.hpp /^ GuiListener* m_guiListener;$/;" m class:AttributeWidget +m_hasTexCoords geoms/Geometry.hpp /^ bool m_hasTexCoords;$/;" m class:Geometry +m_height modules/DepthCamModule.hpp /^ uint16_t m_width, m_height, m_fps;$/;" m class:DepthCamModule +m_height modules/ProjectorModule.hpp /^ float m_width, m_height;$/;" m class:ProjectorModule +m_height modules/RevealedCutModule.hpp /^ int m_posX, m_posY, m_width, m_height;$/;" m class:CutWindow +m_horizontalFOV modules/DepthCamModule.hpp /^ double m_horizontalFOV, m_verticalFOV;$/;" m class:DepthCamModule +m_id osc/OscManager.hpp /^ std::string m_id;$/;" m struct:OscStream +m_image modules/RevealedModule.hpp /^ Fl_Shared_Image* m_image;$/;" m class:RevealedLayerImage +m_imageSize modules/ProjectorModule.hpp /^ cv::Size m_imageSize;$/;" m class:ProjectorModule +m_imageTracker modules/DepthCamModule.hpp /^ ImageTracker* m_imageTracker;$/;" m class:DepthCamModule +m_images modules/RevealedModule.hpp /^ std::vector<Fl_Shared_Image*> m_images;$/;" m class:RevealedLayerAnim +m_imgData modules/RevealedCutModule.hpp /^ uchar* m_imgData;$/;" m class:CutWindow +m_imgFolder modules/DepthCamModule.hpp /^ std::string m_imgFolder;$/;" m class:ImageTracker +m_indexBuffer geoms/Geometry.hpp /^ GLuint m_indexBuffer;$/;" m struct:ContextGeometry +m_indexBufferData geoms/Geometry.hpp /^ std::vector<GLuint> m_indexBufferData;$/;" m class:Geometry +m_init modules/RevealedCutModule.hpp /^ bool m_init;$/;" m class:CutWindow +m_initialized modules/PreviewModule.hpp /^ bool m_initialized;$/;" m class:PreviewModule +m_initialized modules/ProjectorModule.hpp /^ bool m_initialized;$/;" m class:ProjectorModule +m_inputs gui/AttributeWidget.hpp /^ std::vector<Fl_Input*> m_inputs;$/;" m class:AttributeWidget +m_inside modules/RevealedModule.hpp /^ int m_inside;$/;" m class:RevealedModule +m_insideAxes modules/RevealedModule.hpp /^ std::vector<std::string> m_insideAxes;$/;" m class:RevealedModule +m_insideIDMap modules/RevealedModule.hpp /^ std::map<int, GLuint> m_insideIDMap;$/;" m class:RevealedModule +m_insideImage modules/RevealedModule.hpp /^ Fl_Shared_Image* m_insideImage;$/;" m class:RevealedModule +m_insideUpMap modules/RevealedModule.hpp /^ std::map<int, bool> m_insideUpMap;$/;" m class:RevealedModule +m_insides modules/RevealedModule.hpp /^ std::vector<std::string> m_insides;$/;" m class:RevealedModule +m_intCallback modules/Attribute.hpp /^ IntCallback* m_intCallback;$/;" m class:Attribute +m_intValues modules/Attribute.hpp /^ std::vector<int> m_intValues;$/;" m class:Attribute +m_intValues osc/OscManager.hpp /^ std::vector<int> m_intValues;$/;" m struct:OscMessage +m_keypoints modules/DepthCamModule.hpp /^ std::vector<std::vector<cv::KeyPoint> > m_keypoints;$/;" m class:ImageTracker +m_label gui/ModuleWidget.hpp /^ std::string m_label;$/;" m class:ModuleWidget +m_label modules/RevealedTextModule.hpp /^ Fl_Box* m_label;$/;" m class:RevealedTextModule +m_layers modules/RevealedModule.hpp /^ std::vector<RevealedLayer*> m_layers;$/;" m class:RevealedModule +m_layersData modules/RevealedModule.hpp /^ char* m_layersData;$/;" m class:RevealedModule +m_layersImages modules/RevealedModule.hpp /^ std::vector<Fl_Shared_Image*> m_layersImages;$/;" m class:RevealedModule +m_layersNb modules/RevealedModule.hpp /^ int m_layersNb;$/;" m class:RevealedModule +m_listener gui/ListenerWidget.hpp /^ Listener* m_listener;$/;" m class:ListenerWidget +m_listenerID modules/Listener.hpp /^ int m_listenerID;$/;" m class:Listener +m_listenerType modules/Listener.hpp /^ std::string m_listenerType;$/;" m class:Listener +m_listeners gui/MainWindow.hpp /^ Fl_Pack* m_listeners;$/;" m class:MainWindow +m_listeners modules/Attribute.hpp /^ std::vector<Listener*> m_listeners;$/;" m class:Attribute +m_listenersBut gui/AttributeWidget.hpp /^ Fl_Toggle_Button* m_listenersBut;$/;" m class:AttributeWidget +m_listenersDeleteVec Reveal.hpp /^ std::vector<Listener*> m_listenersDeleteVec;$/;" m class:Reveal +m_listenersMap modules/Attribute.hpp /^ std::map<int, Listener*> m_listenersMap;$/;" m class:Attribute +m_loadable modules/Attribute.hpp /^ bool m_loadable;$/;" m class:Attribute +m_localInsideAxes modules/GeomModule.hpp /^ bool m_localInsideAxes;$/;" m class:GeomModule +m_lookAt modules/PreviewModule.hpp /^ glm::vec3 m_lookAt;$/;" m class:PreviewModule +m_markTexMap modules/DepthCamModule.hpp /^ std::map<int, GLuint> m_markTexMap;$/;" m class:DepthCamModule +m_markTexUpMap modules/DepthCamModule.hpp /^ std::map<int, bool> m_markTexUpMap;$/;" m class:DepthCamModule +m_markerPosY modules/DepthCamModule.hpp /^ int m_markerPosY;$/;" m class:DepthCamModule +m_markerRotX modules/DepthCamModule.hpp /^ int m_markerRotX;$/;" m class:DepthCamModule +m_markerRotY modules/DepthCamModule.hpp /^ int m_markerRotY;$/;" m class:DepthCamModule +m_markersFrame modules/DepthCamModule.hpp /^ unsigned char *m_markersFrame;$/;" m class:DepthCamModule +m_markersThread modules/DepthCamModule.hpp /^ std::thread* m_markersThread;$/;" m class:DepthCamModule +m_matcher modules/DepthCamModule.hpp /^ cv::Ptr<cv::DescriptorMatcher> m_matcher;$/;" m class:ImageTracker +m_maxNbDepthCams Reveal.hpp /^ int m_maxNbDepthCams;$/;" m class:Reveal +m_maxNbMarkers modules/DepthCamModule.hpp /^ int m_maxNbMarkers;$/;" m class:DepthCamModule +m_maxNbRevealed Reveal.hpp /^ int m_maxNbRevealed;$/;" m class:Reveal +m_measurePixelNb Reveal.hpp /^ std::map<int, int> m_measurePixelNb;$/;" m class:Reveal +m_measurePixelTimes Reveal.hpp /^ std::map<int, int> m_measurePixelTimes;$/;" m class:Reveal +m_measureTime Reveal.hpp /^ timeval m_measureTime;$/;" m class:Reveal +m_measuring Reveal.hpp /^ bool m_measuring;$/;" m class:Reveal +m_meshGeom modules/DepthMeshModule.hpp /^ Geometry* m_meshGeom;$/;" m class:DepthMeshModule +m_messageSize osc/OscManager.hpp /^ size_t m_messageSize;$/;" m class:OscManager +m_messagesRingBuffer osc/OscManager.hpp /^ jack_ringbuffer_t* m_messagesRingBuffer;$/;" m class:OscManager +m_mirrored modules/DepthCamModule.hpp /^ bool m_mirrored;$/;" m class:DepthCamModule +m_mirrored modules/ProjectorModule.hpp /^ bool m_mirrored;$/;" m class:ProjectorModule +m_modelGeom modules/ModelModule.hpp /^ Geometry* m_modelGeom;$/;" m class:ModelModule +m_modelMat modules/Module.hpp /^ glm::mat4 m_modelMat;$/;" m class:Module +m_modes modules/DepthCamModule.hpp /^ std::vector<std::string> m_modes;$/;" m class:DepthCamModule +m_module gui/ModuleWidget.hpp /^ Module* m_module;$/;" m class:ModuleWidget +m_module modules/Attribute.hpp /^ Module* m_module;$/;" m class:Attribute +m_module modules/RevealedPathModule.hpp /^ Module* m_module;$/;" m class:PathPointModule +m_moduleButtonsMap gui/MainWindow.hpp /^ std::map<std::string, ModuleWidget*> m_moduleButtonsMap;$/;" m class:MainWindow +m_moduleListObsID Reveal.hpp /^ unsigned int m_moduleListObsID;$/;" m class:ModuleListObserver +m_moduleListObservers Reveal.hpp /^ std::map<unsigned int, ModuleListObserver*> m_moduleListObservers;$/;" m class:Reveal +m_moduleName modules/RevealedPathModule.hpp /^ std::string m_moduleName;$/;" m class:PathPointModule +m_modules geoms/Geometry.hpp /^ std::vector<GeomModule*> m_modules;$/;" m class:Geometry +m_modules gui/MainWindow.hpp /^ Fl_Pack* m_modules;$/;" m class:MainWindow +m_modulesDeleteVec Reveal.hpp /^ std::vector<Module*> m_modulesDeleteVec;$/;" m class:Reveal +m_modulesMap Reveal.hpp /^ std::map<std::string, Module*> m_modulesMap;$/;" m class:Reveal +m_modulesMap geoms/Geometry.hpp /^ std::map<unsigned int, GeomModule*> m_modulesMap;$/;" m class:Geometry +m_name gui/AttributeWidget.hpp /^ std::string m_name;$/;" m class:AttributeWidget +m_name modules/Attribute.hpp /^ std::string m_name; $/;" m class:Attribute +m_name modules/Module.hpp /^ std::string m_name;$/;" m class:Module +m_name modules/RevealedCutModule.hpp /^ std::string m_name;$/;" m class:CutWindow +m_name osc/OscManager.hpp /^ std::string m_name;$/;" m struct:OscMessage +m_nbEdges modules/RevealedPathModule.hpp /^ int m_nbEdges;$/;" m class:RevealedPathModule +m_nbPixPerRow modules/RevealedCutModule.hpp /^ int m_nbPixPerRow;$/;" m class:RevealedCutModule +m_nbValues gui/AttributeWidget.hpp /^ unsigned int m_nbValues;$/;" m class:AttributeWidget +m_nbValues modules/Attribute.hpp /^ unsigned int m_nbValues;$/;" m class:Attribute +m_near modules/PreviewModule.hpp /^ float m_near;$/;" m class:PreviewModule +m_neededFramesNb modules/ProjectorModule.hpp /^ int m_neededFramesNb;$/;" m class:ProjectorModule +m_notVoronoi modules/DepthCamModule.hpp /^ bool m_notVoronoi;$/;" m class:DepthCamModule +m_offsetX modules/RevealedCutModule.hpp /^ int m_offsetX, m_offsetY, m_pixPerRow;$/;" m class:CutWindow +m_offsetY modules/RevealedCutModule.hpp /^ int m_offsetX, m_offsetY, m_pixPerRow;$/;" m class:CutWindow +m_open modules/DepthCamModule.hpp /^ bool m_open;$/;" m class:DepthCamModule +m_openPlanned Reveal.hpp /^ int m_openPlanned;$/;" m class:Reveal +m_openPlannedName Reveal.hpp /^ std::string m_openPlannedName;$/;" m class:Reveal +m_outBlobSize modules/ProjectorModule.hpp /^ int m_outBlobSize;$/;" m class:ProjectorModule +m_outDepthSize modules/ProjectorModule.hpp /^ int m_outDepthSize;$/;" m class:ProjectorModule +m_outNbDepth modules/ProjectorModule.hpp /^ int m_outNbDepth;$/;" m class:ProjectorModule +m_outShapeSize modules/ProjectorModule.hpp /^ int m_outShapeSize;$/;" m class:ProjectorModule +m_output gui/AttributeWidget.hpp /^ Fl_Output* m_output;$/;" m class:AttributeWidget +m_outputActive modules/RevealedModule.hpp /^ bool m_outputActive;$/;" m class:RevealedModule +m_outputImg modules/ProjectorModule.hpp /^ unsigned char* m_outputImg;$/;" m class:ProjectorModule +m_outputImgInit modules/ProjectorModule.hpp /^ unsigned char* m_outputImgInit;$/;" m class:ProjectorModule +m_outputImgSize modules/ProjectorModule.hpp /^ unsigned int m_outputImgSize;$/;" m class:ProjectorModule +m_outputTex modules/ProjectorModule.hpp /^ GLuint m_outputTex;$/;" m class:ProjectorModule +m_parameters gui/ListenerWidget.hpp /^ std::vector<Fl_Input*> m_parameters;$/;" m class:ListenerWidget +m_parameters modules/Listener.hpp /^ std::vector<std::string> m_parameters;$/;" m class:Listener +m_parent modules/Module.hpp /^ GroupModule* m_parent;$/;" m class:Module +m_parentMat modules/Module.hpp /^ glm::mat4 m_parentMat;$/;" m class:Module +m_parentVisible modules/Module.hpp /^ bool m_parentVisible;$/;" m class:Module +m_path modules/RevealedPathModule.hpp /^ RevealedPathModule* m_path;$/;" m class:PathPointModule +m_pathGeom modules/RevealedPathModule.hpp /^ Geometry* m_pathGeom;$/;" m class:RevealedPathModule +m_patternBrightness modules/ProjectorModule.hpp /^ int m_patternBrightness;$/;" m class:ProjectorModule +m_patternPosition modules/ProjectorModule.hpp /^ cv::Size m_patternPosition; $/;" m class:ProjectorModule +m_patternPositionX modules/DepthCamModule.hpp /^ int m_patternPositionX;$/;" m class:DepthCamModule +m_patternPositionY modules/DepthCamModule.hpp /^ int m_patternPositionY;$/;" m class:DepthCamModule +m_patternSize modules/DepthCamModule.hpp /^ cv::Size m_patternSize;$/;" m class:DepthCamModule +m_patternSize modules/ProjectorModule.hpp /^ cv::Size m_patternSize;$/;" m class:ProjectorModule +m_patternSquareWidth modules/ProjectorModule.hpp /^ int m_patternSquareWidth; $/;" m class:ProjectorModule +m_patternThresh modules/ProjectorModule.hpp /^ int m_patternThresh;$/;" m class:ProjectorModule +m_patternWidth modules/DepthCamModule.hpp /^ int m_patternWidth;$/;" m class:DepthCamModule +m_pixPerRow modules/RevealedCutModule.hpp /^ int m_offsetX, m_offsetY, m_pixPerRow;$/;" m class:CutWindow +m_playing modules/RevealedModule.hpp /^ bool m_playing;$/;" m class:RevealedLayer +m_point modules/RevealedPathModule.hpp /^ glm::vec4 m_point;$/;" m class:PathPoint +m_points geoms/Geometry.hpp /^ bool m_points;$/;" m class:Geometry +m_points modules/RevealedPathModule.hpp /^ std::vector<PathPoint*> m_points;$/;" m class:RevealedPathModule +m_port osc/OscListener.hpp /^ unsigned int m_port;$/;" m class:OscListener +m_port osc/OscManager.hpp /^ int m_port;$/;" m struct:OscStream +m_posX modules/ProjectorModule.hpp /^ float m_posX, m_posY;$/;" m class:ProjectorModule +m_posX modules/RevealedCutModule.hpp /^ int m_posX, m_posY, m_width, m_height;$/;" m class:CutWindow +m_posY modules/ProjectorModule.hpp /^ float m_posX, m_posY;$/;" m class:ProjectorModule +m_posY modules/RevealedCutModule.hpp /^ int m_posX, m_posY, m_width, m_height;$/;" m class:CutWindow +m_position modules/Module.hpp /^ glm::vec3 m_position;$/;" m class:Module +m_prevTime Reveal.hpp /^ timeval m_prevTime;$/;" m class:Reveal +m_preview Reveal.hpp /^ PreviewModule* m_preview;$/;" m class:Reveal +m_previewWindow modules/PreviewModule.hpp /^ GLFWwindow* m_previewWindow;$/;" m class:PreviewModule +m_processOutput modules/ProjectorModule.hpp /^ bool m_processOutput;$/;" m class:ProjectorModule +m_program modules/PreviewModule.hpp /^ GLint m_program;$/;" m class:PreviewModule +m_programs modules/ProjectorModule.hpp /^ std::map<Reveal::REVIL_PROGRAM, GLint> m_programs;$/;" m class:ProjectorModule +m_projID modules/ProjectorModule.hpp /^ int m_projID;$/;" m class:ProjectorModule +m_projMat modules/PreviewModule.hpp /^ glm::mat4 m_projMat;$/;" m class:PreviewModule +m_projMat modules/ProjectorModule.hpp /^ glm::mat4 m_projMat;$/;" m class:ProjectorModule +m_projModules modules/SpaceModule.hpp /^ std::vector<ProjectorModule*> m_projModules;$/;" m class:SpaceModule +m_projWindow modules/ProjectorModule.hpp /^ GLFWwindow* m_projWindow;$/;" m class:ProjectorModule +m_projectedImg modules/ProjectorModule.hpp /^ cv::Mat m_projectedImg;$/;" m class:ProjectorModule +m_redTexSize modules/RevealedModule.hpp /^ int m_redTexSize;$/;" m class:RevealedModule +m_redXmm modules/DepthCamModule.hpp /^ int m_redXmm, m_redYmm, m_redZmm;$/;" m class:DepthCamModule +m_redYmm modules/DepthCamModule.hpp /^ int m_redXmm, m_redYmm, m_redZmm;$/;" m class:DepthCamModule +m_redZmm modules/DepthCamModule.hpp /^ int m_redXmm, m_redYmm, m_redZmm;$/;" m class:DepthCamModule +m_refresh geoms/Geometry.hpp /^ bool m_refresh;$/;" m struct:ContextGeometry +m_registeredOutputDepthCams Reveal.hpp /^ std::vector<DepthCamModule*> m_registeredOutputDepthCams;$/;" m class:Reveal +m_registeredOutputRevealed Reveal.hpp /^ std::vector<RevealedModule*> m_registeredOutputRevealed;$/;" m class:Reveal +m_removeBut gui/ListenerWidget.hpp /^ Fl_Button* m_removeBut;$/;" m class:ListenerWidget +m_removedMarkers modules/DepthCamModule.hpp /^ std::vector<s_markerAndTime> m_removedMarkers;$/;" m class:DepthCamModule +m_resImg modules/DepthCamModule.hpp /^ cv::Mat m_resImg;$/;" m class:DepthCamModule +m_revAttributes modules/RevealedModule.hpp /^ std::vector<Attribute*> m_revAttributes;$/;" m class:RevealedModule +m_revBlob modules/ProjectorModule.hpp /^ float m_revSurf, m_revIns, m_revCent, m_revCol, m_revBlob;$/;" m class:ProjectorModule +m_revCent modules/ProjectorModule.hpp /^ float m_revSurf, m_revIns, m_revCent, m_revCol, m_revBlob;$/;" m class:ProjectorModule +m_revCol modules/ProjectorModule.hpp /^ float m_revSurf, m_revIns, m_revCent, m_revCol, m_revBlob;$/;" m class:ProjectorModule +m_revID modules/RevealedModule.hpp /^ unsigned int m_revID;$/;" m class:RevealedModule +m_revIDBit modules/RevealedModule.hpp /^ float m_revIDBit;$/;" m class:RevealedModule +m_revIns modules/ProjectorModule.hpp /^ float m_revSurf, m_revIns, m_revCent, m_revCol, m_revBlob;$/;" m class:ProjectorModule +m_revSurf modules/ProjectorModule.hpp /^ float m_revSurf, m_revIns, m_revCent, m_revCol, m_revBlob;$/;" m class:ProjectorModule +m_revealedBy modules/Module.hpp /^ int m_revealedBy;$/;" m class:Module +m_revealedBys modules/Module.hpp /^ std::vector<std::string> m_revealedBys;$/;" m class:Module +m_revealedMap Reveal.hpp /^ std::map<unsigned int, RevealedModule*> m_revealedMap;$/;" m class:Reveal +m_revealedVec Reveal.hpp /^ std::vector<RevealedModule*> m_revealedVec;$/;" m class:Reveal +m_rgbDepthImg modules/DepthCamModule.hpp /^ cv::Mat m_rgbDepthImg;$/;" m class:DepthCamModule +m_rgbImg modules/DepthCamModule.hpp /^ cv::Mat m_rgbImg;$/;" m class:DepthCamModule +m_rotEuler modules/Module.hpp /^ glm::vec3 m_rotEuler;$/;" m class:Module +m_rotMat modules/Module.hpp /^ glm::mat4 m_rotMat;$/;" m class:Module +m_rotQuat modules/Module.hpp /^ glm::quat m_rotQuat;$/;" m class:Module +m_rows modules/DepthCamModule.hpp /^ std::vector<int> m_rows;$/;" m class:ImageTracker +m_rttHeight modules/ProjectorModule.hpp /^ int m_rttWidth, m_rttHeight;$/;" m class:ProjectorModule +m_rttWidth modules/ProjectorModule.hpp /^ int m_rttWidth, m_rttHeight;$/;" m class:ProjectorModule +m_scale modules/Module.hpp /^ glm::vec3 m_scale;$/;" m class:Module +m_scene Reveal.hpp /^ RootSceneGroupModule* m_scene;$/;" m class:Reveal +m_scrollAttributes gui/MainWindow.hpp /^ Fl_Scroll* m_scrollAttributes;$/;" m class:MainWindow +m_scrollListeners gui/MainWindow.hpp /^ Fl_Scroll* m_scrollListeners;$/;" m class:MainWindow +m_scrollModules gui/MainWindow.hpp /^ Fl_Scroll* m_scrollModules;$/;" m class:MainWindow +m_selectFBO modules/ProjectorModule.hpp /^ GLuint m_selectFBO;$/;" m class:ProjectorModule +m_selectTex modules/ProjectorModule.hpp /^ GLuint m_selectTex;$/;" m class:ProjectorModule +m_selectedModulePath gui/MainWindow.hpp /^ std::string m_selectedModulePath;$/;" m class:MainWindow +m_sentDetectedMarkers modules/DepthCamModule.hpp /^ std::vector<s_markerAndTime> m_sentDetectedMarkers;$/;" m class:DepthCamModule +m_sentRemovedMarkers modules/DepthCamModule.hpp /^ std::vector<s_markerAndTime> m_sentRemovedMarkers;$/;" m class:DepthCamModule +m_shapes modules/ShapeModule.hpp /^ std::vector<std::string> m_shapes;$/;" m class:ShapeModule +m_shapesMap modules/ShapeModule.hpp /^ std::map<std::string, Reveal::GEOM_ID> m_shapesMap;$/;" m class:ShapeModule +m_sliceFBO modules/ProjectorModule.hpp /^ GLuint m_sliceFBO;$/;" m class:ProjectorModule +m_sliceRttTex modules/ProjectorModule.hpp /^ GLuint m_sliceRttTex;$/;" m class:ProjectorModule +m_sliceSmpTex modules/ProjectorModule.hpp /^ GLuint m_sliceSmpTex;$/;" m class:ProjectorModule +m_sliceTex modules/ProjectorModule.hpp /^ GLuint m_sliceTex;$/;" m class:ProjectorModule +m_socket osc/OscManager.hpp /^ UdpListeningReceiveSocket* m_socket;$/;" m class:OscManager +m_space modules/DepthModule.hpp /^ SpaceModule* m_space;$/;" m class:DepthModule +m_space modules/ProjectorModule.hpp /^ SpaceModule* m_space;$/;" m class:ProjectorModule +m_spaces Reveal.hpp /^ SpacesModule* m_spaces;$/;" m class:Reveal +m_speed modules/RevealedModule.hpp /^ float m_speed;$/;" m class:RevealedLayer +m_srcCoords modules/RevealedCutModule.hpp /^ std::vector<std::vector<int> > m_srcCoords;$/;" m class:RevealedCutModule +m_srcIndices modules/RevealedCutModule.hpp /^ std::vector<int> m_srcIndices;$/;" m class:RevealedCutModule +m_strValues osc/OscManager.hpp /^ std::vector<std::string> m_strValues;$/;" m struct:OscMessage +m_stream osc/OscManager.hpp /^ osc::OutboundPacketStream* m_stream;$/;" m struct:OscStream +m_streams modules/DepthCamModule.hpp /^ openni::VideoStream** m_streams;$/;" m class:DepthCamModule +m_streamsMap osc/OscManager.hpp /^ std::map<std::string, OscStream*> m_streamsMap;$/;" m class:OscManager +m_streamsVec osc/OscManager.hpp /^ std::vector<OscStream*> m_streamsVec;$/;" m class:OscManager +m_stringCallback modules/Attribute.hpp /^ StringCallback* m_stringCallback;$/;" m class:Attribute +m_stringIsChoice gui/AttributeWidget.hpp /^ std::vector<bool> m_stringIsChoice;$/;" m class:AttributeWidget +m_stringValues modules/Attribute.hpp /^ std::vector<std::string> m_stringValues;$/;" m class:Attribute +m_stringValuesChoices modules/Attribute.hpp /^ std::vector<std::vector<std::string> > m_stringValuesChoices;$/;" m class:Attribute +m_surface modules/RevealedModule.hpp /^ int m_surface;$/;" m class:RevealedModule +m_surfaceIDMap modules/RevealedModule.hpp /^ std::map<int, GLuint> m_surfaceIDMap;$/;" m class:RevealedModule +m_surfaceImage modules/RevealedModule.hpp /^ Fl_Shared_Image* m_surfaceImage;$/;" m class:RevealedModule +m_surfaceThickness modules/RevealedModule.hpp /^ float m_surfaceThickness;$/;" m class:RevealedModule +m_surfaceUpMap modules/RevealedModule.hpp /^ std::map<int, bool> m_surfaceUpMap;$/;" m class:RevealedModule +m_surfaces modules/RevealedModule.hpp /^ std::vector<std::string> m_surfaces;$/;" m class:RevealedModule +m_texHeight modules/Module.hpp /^ int m_texHeight;$/;" m class:Module +m_texMirrors modules/RevealedModule.hpp /^ std::vector<std::string> m_texMirrors;$/;" m class:RevealedModule +m_texWidth modules/Module.hpp /^ int m_texWidth;$/;" m class:Module +m_text modules/RevealedCutModule.hpp /^ std::string m_text;$/;" m class:RevealedCutModule +m_text modules/RevealedTextModule.hpp /^ std::string m_text;$/;" m class:RevealedTextModule +m_textImg modules/RevealedTextModule.hpp /^ Fl_RGB_Image* m_textImg;$/;" m class:RevealedTextModule +m_textureOffset modules/RevealedModule.hpp /^ float m_textureOffset[3];$/;" m class:RevealedModule +m_textureScale modules/RevealedModule.hpp /^ float m_textureScale[3];$/;" m class:RevealedModule +m_thickness modules/RevealedPathModule.hpp /^ float m_thickness;$/;" m class:RevealedPathModule +m_thread osc/OscManager.hpp /^ pthread_t m_thread;$/;" m class:OscManager +m_timeDiffMs modules/RevealedModule.hpp /^ int m_timeDiffMs;$/;" m class:RevealedModule +m_transViewMat modules/ProjectorModule.hpp /^ glm::mat4 m_transViewMat;$/;" m class:ProjectorModule +m_transform modules/Module.hpp /^ glm::mat4 m_transform;$/;" m class:Module +m_treeWidth gui/MainWindow.hpp /^ int m_treeWidth;$/;" m class:MainWindow +m_type modules/Attribute.hpp /^ TYPE m_type;$/;" m class:Attribute +m_type modules/Module.hpp /^ std::string m_type;$/;" m class:Module +m_typesMap Reveal.hpp /^ std::map<std::string, Module*> m_typesMap;$/;" m class:Reveal +m_uniforms modules/PreviewModule.hpp /^ std::map<Reveal::REVIL_UNIFORM, GLint> m_uniforms;$/;" m class:PreviewModule +m_uniforms modules/ProjectorModule.hpp /^ std::map<Reveal::REVIL_UNIFORM, GLint> > m_uniforms;$/;" m class:ProjectorModule +m_upCamCounter modules/DepthCamModule.hpp /^ std::map<int, int> m_upCamCounter;$/;" m class:DepthCamModule +m_upID modules/Module.hpp /^ int m_upID;$/;" m class:Module +m_upObsIdCounter Reveal.hpp /^ unsigned int m_upObsIdCounter;$/;" m class:Reveal +m_update modules/RevealedModule.hpp /^ bool m_update;$/;" m class:RevealedLayer +m_updateObservers Reveal.hpp /^ std::vector<Module*> m_updateObservers;$/;" m class:Reveal +m_updateOnce modules/RevealedCutModule.hpp /^ bool m_updateOnce;$/;" m class:RevealedCutModule +m_updateOnceDone modules/RevealedCutModule.hpp /^ bool m_updateOnceDone;$/;" m class:RevealedCutModule +m_upsideDown modules/DepthCamModule.hpp /^ bool m_upsideDown;$/;" m class:DepthCamModule +m_url osc/OscListener.hpp /^ std::string m_url;$/;" m class:OscListener +m_valueInputs gui/AttributeWidget.hpp /^ std::vector<Fl_Value_Input*> m_valueInputs;$/;" m class:AttributeWidget +m_valuesLabels modules/Attribute.hpp /^ std::vector<std::string> m_valuesLabels;$/;" m class:Attribute +m_valuesMax modules/Attribute.hpp /^ std::vector<float> m_valuesMax;$/;" m class:Attribute +m_valuesMin modules/Attribute.hpp /^ std::vector<float> m_valuesMin;$/;" m class:Attribute +m_vertexArrayID geoms/Geometry.hpp /^ GLuint m_vertexArrayID;$/;" m struct:ContextGeometry +m_vertexBuffer geoms/Geometry.hpp /^ GLuint m_vertexBuffer;$/;" m struct:ContextGeometry +m_vertexBufferData geoms/Geometry.hpp /^ std::vector<GLfloat> m_vertexBufferData;$/;" m class:Geometry +m_verticalFOV modules/DepthCamModule.hpp /^ double m_horizontalFOV, m_verticalFOV;$/;" m class:DepthCamModule +m_video modules/RevealedModule.hpp /^ cv::VideoCapture m_video;$/;" m class:RevealedLayerVideo +m_viewMat modules/PreviewModule.hpp /^ glm::mat4 m_viewMat;$/;" m class:PreviewModule +m_viewMat modules/ProjectorModule.hpp /^ glm::mat4 m_viewMat;$/;" m class:ProjectorModule +m_viewProjMat modules/PreviewModule.hpp /^ glm::mat4 m_viewProjMat;$/;" m class:PreviewModule +m_viewProjMat modules/ProjectorModule.hpp /^ glm::mat4 m_viewProjMat;$/;" m class:ProjectorModule +m_viewProjUniform modules/PreviewModule.hpp /^ GLint m_viewProjUniform;$/;" m class:PreviewModule +m_visibilityMask modules/Module.hpp /^ int m_visibilityMask;$/;" m class:Module +m_visible modules/Module.hpp /^ bool m_visible;$/;" m class:Module +m_visibleFromMap Reveal.hpp /^ std::map<std::string, int> m_visibleFromMap;$/;" m class:Reveal +m_visibleFromVec Reveal.hpp /^ std::vector<std::string> m_visibleFromVec;$/;" m class:Reveal +m_volumeTextureHeight modules/RevealedModule.hpp /^ int m_volumeTextureHeight;$/;" m class:RevealedModule +m_volumeTextureWidth modules/RevealedModule.hpp /^ int m_volumeTextureWidth;$/;" m class:RevealedModule +m_width modules/DepthCamModule.hpp /^ uint16_t m_width, m_height, m_fps;$/;" m class:DepthCamModule +m_width modules/ProjectorModule.hpp /^ float m_width, m_height;$/;" m class:ProjectorModule +m_width modules/RevealedCutModule.hpp /^ int m_posX, m_posY, m_width, m_height;$/;" m class:CutWindow +m_win modules/RevealedCutModule.hpp /^ Window m_win;$/;" m class:CutWindow +m_winH modules/RevealedCutModule.hpp /^ int m_winX, m_winY, m_winW, m_winH;$/;" m class:RevealedCutModule +m_winID modules/RevealedCutModule.hpp /^ int m_winID;$/;" m class:CutWindow +m_winW modules/RevealedCutModule.hpp /^ int m_winX, m_winY, m_winW, m_winH;$/;" m class:RevealedCutModule +m_winX modules/RevealedCutModule.hpp /^ int m_winX, m_winY, m_winW, m_winH;$/;" m class:RevealedCutModule +m_winY modules/RevealedCutModule.hpp /^ int m_winX, m_winY, m_winW, m_winH;$/;" m class:RevealedCutModule +m_windowList modules/RevealedCutModule.hpp /^ std::vector<CutWindow*> m_windowList;$/;" m class:CutWindowsManager +m_windowMap modules/RevealedCutModule.hpp /^ std::map<unsigned int, CutWindow*> m_windowMap;$/;" m class:CutWindowsManager +m_winsMan modules/RevealedCutModule.hpp /^ CutWindowsManager* m_winsMan;$/;" m class:CutWindow +m_worldCorners modules/DepthCamModule.hpp /^ std::vector<cv::Point3f> m_worldCorners;$/;" m class:DepthCamModule +m_ximg modules/RevealedCutModule.hpp /^ XImage* m_ximg;$/;" m class:CutWindow +main Reveal.cpp /^int main( int argc, char **argv ) {$/;" f +markersDetectionCallback modules/DepthCamModule.hpp /^ static void markersDetectionCallback(Module* mod,$/;" f class:DepthCamModule +markersDetectionMethodCallback modules/DepthCamModule.hpp /^ static void markersDetectionMethodCallback(Module* mod,$/;" f class:DepthCamModule +markersThreadFunction modules/DepthCamModule.cpp /^void* markersThreadFunction(void* pvParam) {$/;" f +measureStart Reveal.cpp /^void Reveal::measureStart() {$/;" f class:Reveal +measureStart Reveal.hpp /^ void measureStart();$/;" p class:Reveal +measureStore Reveal.cpp /^void Reveal::measureStore(const int& nbPixels) {$/;" f class:Reveal +measureStore Reveal.hpp /^ void measureStore(const int& nbPixels);$/;" p class:Reveal +messageCursor_ osc/oscPack/osc/OscOutboundPacketStream.h /^ char *messageCursor_;$/;" m class:osc::OutboundPacketStream +messageIsInProgress_ osc/oscPack/osc/OscOutboundPacketStream.h /^ bool messageIsInProgress_;$/;" m class:osc::OutboundPacketStream +mirroredCallback modules/ProjectorModule.hpp /^ static void mirroredCallback(Module* mod, $/;" f class:ProjectorModule +mlocked osc/ringbuffer.c /^ int mlocked;$/;" m struct:__anon7 file: +mlocked osc/ringbuffer.h /^ int mlocked;$/;" m struct:__anon2 +modeCallback modules/DepthCamModule.hpp /^ static void modeCallback(Module* mod,$/;" f class:DepthCamModule +modelCallback modules/ModelModule.hpp /^ static void modelCallback(Module* mod, $/;" f class:ModelModule +multiplexerInstanceToAbortWithSigInt_ osc/oscPack/ip/posix/UdpSocket.cpp /^SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0;$/;" v +multiplexerInstanceToAbortWithSigInt_ osc/oscPack/ip/win32/UdpSocket.cpp /^SocketReceiveMultiplexer *multiplexerInstanceToAbortWithSigInt_ = 0;$/;" v +mux_ osc/oscPack/ip/UdpSocket.h /^ SocketReceiveMultiplexer mux_;$/;" m class:UdpListeningReceiveSocket +nameCallback modules/DepthGroupModule.hpp /^ static void nameCallback(Module* mod, $/;" f class:DepthGroupModule +nameCallback modules/Module.hpp /^ static void nameCallback(Module* mod, $/;" f class:Module +nameCallback modules/SceneGroupModule.hpp /^ static void nameCallback(Module* mod, $/;" f class:SceneGroupModule +networkInitializer_ osc/oscPack/ip/win32/UdpSocket.cpp /^ NetworkInitializer networkInitializer_;$/;" m class:SocketReceiveMultiplexer::Implementation file: +networkInitializer_ osc/oscPack/ip/win32/UdpSocket.cpp /^ NetworkInitializer networkInitializer_;$/;" m class:UdpSocket::Implementation file: +newSetOfPoint modules/DepthCamModule.cpp /^vector<cv::Point2f> DepthCamModule::newSetOfPoint(vector<cv::Point2f> points, $/;" f class:DepthCamModule +newSetOfPoint modules/DepthCamModule.hpp /^ std::vector<cv::Point2f> newSetOfPoint(std::vector<cv::Point2f> points, $/;" p class:DepthCamModule +open Reveal.cpp /^void Reveal::open(const std::string& fileName) {$/;" f class:Reveal +open Reveal.hpp /^ void open(const std::string& f);$/;" p class:Reveal +openCallback Reveal.hpp /^ static void openCallback(Module* mod, const std::string& f) {$/;" f class:Reveal +openDevice modules/DepthCamModule.cpp /^void DepthCamModule::openDevice(const std::string& devStr, bool calib) {$/;" f class:DepthCamModule +openDevice modules/DepthCamModule.hpp /^ virtual void openDevice(const std::string& dev, bool calib=false);$/;" p class:DepthCamModule +operator != osc/oscPack/ip/IpEndpointName.h /^inline bool operator!=( const IpEndpointName& lhs, const IpEndpointName& rhs )$/;" f +operator != osc/oscPack/osc/OscReceivedElements.h /^inline bool operator!=(const ReceivedBundleElementIterator& lhs,$/;" f namespace:osc +operator != osc/oscPack/osc/OscReceivedElements.h /^inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,$/;" f namespace:osc +operator () osc/oscPack/osc/MessageMappingOscPacketListener.h /^ bool operator()( const char *lhs, const char *rhs ) const$/;" f struct:osc::MessageMappingOscPacketListener::cstr_compare +operator * osc/oscPack/osc/OscReceivedElements.h /^ const ReceivedBundleElement& operator*() const { return value_; }$/;" f class:osc::ReceivedBundleElementIterator +operator * osc/oscPack/osc/OscReceivedElements.h /^ const ReceivedMessageArgument& operator*() const { return value_; }$/;" f class:osc::ReceivedMessageArgumentIterator +operator ++ osc/oscPack/osc/OscReceivedElements.h /^ ReceivedBundleElementIterator operator++()$/;" f class:osc::ReceivedBundleElementIterator +operator ++ osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentIterator operator++()$/;" f class:osc::ReceivedMessageArgumentIterator +operator ++ osc/oscPack/osc/OscReceivedElements.h /^ ReceivedBundleElementIterator operator++(int)$/;" f class:osc::ReceivedBundleElementIterator +operator ++ osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentIterator operator++(int)$/;" f class:osc::ReceivedMessageArgumentIterator +operator -> osc/oscPack/osc/OscReceivedElements.h /^ const ReceivedBundleElement* operator->() const { return &value_; }$/;" f class:osc::ReceivedBundleElementIterator +operator -> osc/oscPack/osc/OscReceivedElements.h /^ const ReceivedMessageArgument* operator->() const { return &value_; }$/;" f class:osc::ReceivedMessageArgumentIterator +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( char rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayInitiator& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const ArrayTerminator& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const BundleTerminator& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( float rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( bool rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( char rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const ArrayInitiator& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const ArrayTerminator& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const BeginMessage& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const Blob& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const BundleInitiator& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const BundleTerminator& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const InfinitumType& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const MessageTerminator& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const MidiMessage& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const NilType& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const RgbaColor& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const Symbol& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const TimeTag& rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( const char* rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( double rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( float rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( int rhs )$/;" f class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( int32 rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscOutboundPacketStream.h /^ OutboundPacketStream& operator<<( int64 rhs );$/;" p class:osc::OutboundPacketStream +operator << osc/oscPack/osc/OscPrintReceivedElements.cpp /^std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b )$/;" f namespace:osc +operator << osc/oscPack/osc/OscPrintReceivedElements.cpp /^std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m )$/;" f namespace:osc +operator << osc/oscPack/osc/OscPrintReceivedElements.cpp /^std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p )$/;" f namespace:osc +operator << osc/oscPack/osc/OscPrintReceivedElements.cpp /^std::ostream& operator<<( std::ostream & os,$/;" f namespace:osc +operator << osc/oscPack/osc/OscPrintReceivedElements.h /^std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b );$/;" p namespace:osc +operator << osc/oscPack/osc/OscPrintReceivedElements.h /^std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m );$/;" p namespace:osc +operator << osc/oscPack/osc/OscPrintReceivedElements.h /^std::ostream& operator<<( std::ostream & os, const ReceivedMessageArgument& arg );$/;" p namespace:osc +operator << osc/oscPack/osc/OscPrintReceivedElements.h /^std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p );$/;" p namespace:osc +operator = osc/oscPack/osc/OscException.h /^ Exception& operator=( const Exception& src ) throw()$/;" f class:osc::Exception +operator == osc/oscPack/ip/IpEndpointName.h /^inline bool operator==( const IpEndpointName& lhs, const IpEndpointName& rhs )$/;" f +operator == osc/oscPack/osc/OscReceivedElements.h /^ friend bool operator==(const ReceivedBundleElementIterator& lhs,$/;" p class:osc::ReceivedBundleElementIterator +operator == osc/oscPack/osc/OscReceivedElements.h /^ friend bool operator==(const ReceivedMessageArgumentIterator& lhs,$/;" p class:osc::ReceivedMessageArgumentIterator +operator == osc/oscPack/osc/OscReceivedElements.h /^inline bool operator==(const ReceivedBundleElementIterator& lhs,$/;" f namespace:osc +operator == osc/oscPack/osc/OscReceivedElements.h /^inline bool operator==(const ReceivedMessageArgumentIterator& lhs,$/;" f namespace:osc +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( Blob& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( Symbol& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( bool& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( char& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( const char*& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( double& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( float& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( int32& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator >> osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentStream& operator>>( int64& rhs )$/;" f class:osc::ReceivedMessageArgumentStream +operator const char * osc/oscPack/osc/OscTypes.h /^ operator const char *() const { return value; }$/;" f struct:osc::Symbol +operator uint32 osc/oscPack/osc/OscTypes.h /^ operator uint32() const { return value; }$/;" f struct:osc::MidiMessage +operator uint32 osc/oscPack/osc/OscTypes.h /^ operator uint32() const { return value; }$/;" f struct:osc::RgbaColor +operator uint64 osc/oscPack/osc/OscTypes.h /^ operator uint64() const { return value; }$/;" f struct:osc::TimeTag +orientation modules/DepthCamModule.hpp /^ glm::vec3 orientation;$/;" m struct:s_markerAndTime +osc osc/oscPack/osc/MessageMappingOscPacketListener.h /^namespace osc{$/;" n +osc osc/oscPack/osc/OscException.h /^namespace osc{$/;" n +osc osc/oscPack/osc/OscOutboundPacketStream.cpp /^namespace osc{$/;" n file: +osc osc/oscPack/osc/OscOutboundPacketStream.h /^namespace osc{$/;" n +osc osc/oscPack/osc/OscPacketListener.h /^namespace osc{$/;" n +osc osc/oscPack/osc/OscPrintReceivedElements.cpp /^namespace osc{$/;" n file: +osc osc/oscPack/osc/OscPrintReceivedElements.h /^namespace osc{$/;" n +osc osc/oscPack/osc/OscReceivedElements.cpp /^namespace osc{$/;" n file: +osc osc/oscPack/osc/OscReceivedElements.h /^namespace osc{$/;" n +osc osc/oscPack/osc/OscTypes.cpp /^namespace osc{$/;" n file: +osc osc/oscPack/osc/OscTypes.h /^namespace osc{$/;" n +oscThreadFunction osc/OscManager.cpp /^void* oscThreadFunction(void* pvParam) {$/;" f +osc_bundle_element_size_t osc/oscPack/osc/OscTypes.h /^typedef int32 osc_bundle_element_size_t;$/;" t namespace:osc +outputMarkers modules/DepthCamModule.hpp /^ inline void outputMarkers(const std::vector<float>& vals){}$/;" f class:DepthCamModule +outputMarkersCallback modules/DepthCamModule.hpp /^ static void outputMarkersCallback(Module* mod,$/;" f class:DepthCamModule +outputRevealed modules/ProjectorModule.cpp /^void ProjectorModule::outputRevealed(bool output) {$/;" f class:ProjectorModule +outputRevealed modules/ProjectorModule.hpp /^ void outputRevealed(bool output);$/;" p class:ProjectorModule +outputRevealedCallback modules/ProjectorModule.hpp /^ static void outputRevealedCallback(Module* mod, $/;" f class:ProjectorModule +p_ osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgumentIterator p_, end_;$/;" m class:osc::ReceivedMessageArgumentStream +periodMs osc/oscPack/ip/posix/UdpSocket.cpp /^ int periodMs;$/;" m struct:AttachedTimerListener file: +periodMs osc/oscPack/ip/win32/UdpSocket.cpp /^ int periodMs;$/;" m struct:AttachedTimerListener file: +plan modules/DepthCamModule.hpp /^ int plan = -1;$/;" m struct:s_markerAndTime +planOpen Reveal.cpp /^void Reveal::planOpen(std::string opSt) {$/;" f class:Reveal +planOpen Reveal.hpp /^ void planOpen(std::string); $/;" p class:Reveal +port osc/oscPack/ip/IpEndpointName.h /^ int port;$/;" m class:IpEndpointName +pos modules/ModelModule.hpp /^ glm::vec3 pos;$/;" m struct:ModelModule::ModelVertex +positionCallback modules/Module.hpp /^ static void positionCallback(Module* mod, $/;" f class:Module +positionCallback modules/SceneGroupModule.hpp /^ static void positionCallback(Module* mod, $/;" f class:SceneGroupModule +processCursor modules/DepthCamModule.cpp /^void DepthCamModule::processCursor(const std::vector<float>& pos) {$/;" f class:DepthCamModule +processCursor modules/DepthCamModule.hpp /^ void processCursor(const std::vector<float>& pos);$/;" p class:DepthCamModule +processOutput modules/ProjectorModule.cpp /^void ProjectorModule::processOutput() {$/;" f class:ProjectorModule +processOutput modules/ProjectorModule.hpp /^ void processOutput();$/;" p class:ProjectorModule +processReveal modules/RevealedModule.cpp /^void RevealedModule::processReveal(const unsigned int& depthID,$/;" f class:RevealedModule +processReveal modules/RevealedModule.hpp /^ virtual void processReveal(const unsigned int& id,$/;" p class:RevealedModule +processReveal modules/RevealedPathModule.cpp /^void RevealedPathModule::processReveal(const vector<string>& names,$/;" f class:RevealedPathModule +processReveal modules/RevealedPathModule.hpp /^ virtual void processReveal(const std::vector<std::string>&, $/;" p class:RevealedPathModule +projectionMatrixCallback modules/ProjectorModule.hpp /^ static void projectionMatrixCallback(Module* mod, $/;" f class:ProjectorModule +quaternionCallback modules/Module.hpp /^ static void quaternionCallback(Module* mod, $/;" f class:Module +quit Reveal.cpp /^void Reveal::quit() {$/;" f class:Reveal +quit Reveal.hpp /^ void quit();$/;" p class:Reveal +quitCallback Reveal.hpp /^ static void quitCallback(Module* mod) {$/;" f class:Reveal +read_ptr osc/ringbuffer.c /^ volatile size_t read_ptr;$/;" m struct:__anon7 file: +read_ptr osc/ringbuffer.h /^ volatile size_t read_ptr;$/;" m struct:__anon2 +recomputePixels modules/RevealedCutModule.cpp /^void RevealedCutModule::recomputePixels() {$/;" f class:RevealedCutModule +recomputePixels modules/RevealedCutModule.hpp /^ void recomputePixels();$/;" p class:RevealedCutModule +refresh geoms/Geometry.cpp /^void Geometry::refresh() {$/;" f class:Geometry +refresh geoms/Geometry.hpp /^ void refresh();$/;" p class:Geometry +refreshDepthCamList modules/ProjectorModule.cpp /^void ProjectorModule::refreshDepthCamList(const vector<DepthCamModule*> cams) {$/;" f class:ProjectorModule +refreshDepthCamList modules/ProjectorModule.hpp /^ void refreshDepthCamList(const std::vector<DepthCamModule*>);$/;" p class:ProjectorModule +refreshDepthCamList modules/SpaceModule.cpp /^void SpaceModule::refreshDepthCamList() {$/;" f class:SpaceModule +refreshDepthCamList modules/SpaceModule.hpp /^ void refreshDepthCamList();$/;" p class:SpaceModule +refreshGeometry modules/RevealedPathModule.cpp /^void RevealedPathModule::refreshGeometry() {$/;" f class:RevealedPathModule +refreshGeometry modules/RevealedPathModule.hpp /^ void refreshGeometry();$/;" p class:RevealedPathModule +refreshModules Reveal.cpp /^void Reveal::refreshModules() {$/;" f class:Reveal +refreshModules Reveal.hpp /^ void refreshModules();$/;" p class:Reveal +refreshModules gui/MainWindow.cpp /^void MainWindow::refreshModules(bool clearAttributes, bool clearListeners) {$/;" f class:MainWindow +refreshModules gui/MainWindow.hpp /^ void refreshModules(bool clearAttributes=false, $/;" p class:MainWindow +refreshMonitors modules/ProjectorModule.cpp /^void ProjectorModule::refreshMonitors(){$/;" f class:ProjectorModule +refreshMonitors modules/ProjectorModule.hpp /^ void refreshMonitors();$/;" p class:ProjectorModule +refreshPos modules/RevealedPathModule.cpp /^void PathPointModule::refreshPos() {$/;" f class:PathPointModule +refreshPos modules/RevealedPathModule.hpp /^ virtual void refreshPos();$/;" p class:PathPointModule +refreshPos modules/RevealedPathModule.hpp /^ virtual void refreshPos(){}$/;" f class:PathPoint +refreshProjList modules/DepthCamModule.cpp /^void DepthCamModule::refreshProjList(const vector<ProjectorModule*> projs) {$/;" f class:DepthCamModule +refreshProjList modules/DepthCamModule.hpp /^ void refreshProjList(const std::vector<ProjectorModule*> projs);$/;" p class:DepthCamModule +refreshProjList modules/SpaceModule.cpp /^void SpaceModule::refreshProjList() {$/;" f class:SpaceModule +refreshProjList modules/SpaceModule.hpp /^ void refreshProjList();$/;" p class:SpaceModule +refreshWindows modules/RevealedCutModule.cpp /^void RevealedCutModule::refreshWindows() {$/;" f class:RevealedCutModule +refreshWindows modules/RevealedCutModule.hpp /^ virtual void refreshWindows();$/;" p class:RevealedCutModule +refreshWindowsCallback modules/RevealedCutModule.hpp /^ static void refreshWindowsCallback(Module* mod) {$/;" f class:RevealedCutModule +registerGeom Reveal.cpp /^void Reveal::registerGeom(Geometry* geom) {$/;" f class:Reveal +registerGeom Reveal.hpp /^ void registerGeom(Geometry* geom);$/;" p class:Reveal +registerGeom modules/SpaceModule.cpp /^void SpaceModule::registerGeom(Geometry* geom) {$/;" f class:SpaceModule +registerGeom modules/SpaceModule.hpp /^ void registerGeom(Geometry* geom);$/;" p class:SpaceModule +registerModule geoms/Geometry.cpp /^void Geometry::registerModule(GeomModule* geom) {$/;" f class:Geometry +registerModule geoms/Geometry.hpp /^ void registerModule(GeomModule*);$/;" p class:Geometry +registerOutputDepthCam Reveal.cpp /^void Reveal::registerOutputDepthCam(DepthCamModule* cam) {$/;" f class:Reveal +registerOutputDepthCam Reveal.hpp /^ void registerOutputDepthCam(DepthCamModule* cam);$/;" p class:Reveal +registerOutputRevealed Reveal.cpp /^void Reveal::registerOutputRevealed(RevealedModule* rev) {$/;" f class:Reveal +registerOutputRevealed Reveal.hpp /^ void registerOutputRevealed(RevealedModule* rev);$/;" p class:Reveal +registerRevealed Reveal.cpp /^void Reveal::registerRevealed(RevealedModule* rev) {$/;" f class:Reveal +registerRevealed Reveal.hpp /^ void registerRevealed(RevealedModule*);$/;" p class:Reveal +releaseImage modules/RevealedCutModule.cpp /^void CutWindow::releaseImage() {$/;" f class:CutWindow +releaseImage modules/RevealedCutModule.hpp /^ void releaseImage();$/;" p class:CutWindow +removeCallback modules/Module.hpp /^ static void removeCallback(Module* mod) {$/;" f class:Module +removeCam modules/SpaceModule.cpp /^void SpaceModule::removeCam(DepthCamModule* cam) {$/;" f class:SpaceModule +removeCam modules/SpaceModule.hpp /^ void removeCam(DepthCamModule*);$/;" p class:SpaceModule +removeChild modules/GroupModule.cpp /^void GroupModule::removeChild(Module* mod) {$/;" f class:GroupModule +removeChild modules/GroupModule.hpp /^ virtual void removeChild(Module* mod);$/;" p class:GroupModule +removeContextHandler Reveal.cpp /^void Reveal::removeContextHandler(ContextHandler* cont) {$/;" f class:Reveal +removeContextHandler Reveal.hpp /^ void removeContextHandler(ContextHandler* cont);$/;" p class:Reveal +removeDepthModule modules/SpaceModule.cpp /^void SpaceModule::removeDepthModule(DepthModule* mod) {$/;" f class:SpaceModule +removeDepthModule modules/SpaceModule.hpp /^ void removeDepthModule(DepthModule*);$/;" p class:SpaceModule +removeListener modules/Attribute.cpp /^void Attribute::removeListener(Listener* lis) {$/;" f class:Attribute +removeListener modules/Attribute.hpp /^ void removeListener(Listener* lis);$/;" p class:Attribute +removeModuleListObserver Reveal.cpp /^void Reveal::removeModuleListObserver(ModuleListObserver* obs) {$/;" f class:Reveal +removeModuleListObserver Reveal.hpp /^ void removeModuleListObserver(ModuleListObserver* obs);$/;" p class:Reveal +removePoint modules/RevealedPathModule.cpp /^void RevealedPathModule::removePoint() {$/;" f class:RevealedPathModule +removePoint modules/RevealedPathModule.hpp /^ void removePoint();$/;" p class:RevealedPathModule +removePointCallback modules/RevealedPathModule.hpp /^ static void removePointCallback(Module* mod) {$/;" f class:RevealedPathModule +removeProj modules/SpaceModule.cpp /^void SpaceModule::removeProj(ProjectorModule* proj) {$/;" f class:SpaceModule +removeProj modules/SpaceModule.hpp /^ void removeProj(ProjectorModule*);$/;" p class:SpaceModule +removeUpdateObserver Reveal.cpp /^void Reveal::removeUpdateObserver(Module* upObs) {$/;" f class:Reveal +removeUpdateObserver Reveal.hpp /^ void removeUpdateObserver(Module* upObs);$/;" p class:Reveal +ressourcesCallback Reveal.hpp /^ static void ressourcesCallback(Module* mod, const std::string& f) {$/;" f class:Reveal +revblobCallback modules/RevealedModule.hpp /^ static void revblobCallback(Module* mod,const std::vector<float>&vals){}$/;" f class:RevealedModule +revcentCallback modules/RevealedModule.hpp /^ static void revcentCallback(Module* mod,const std::vector<float>&vals){}$/;" f class:RevealedModule +revcolCallback modules/RevealedModule.hpp /^ static void revcolCallback(Module* mod,const std::vector<float>& vals){}$/;" f class:RevealedModule +revealedByCallback modules/Module.hpp /^ static void revealedByCallback(Module* mod, $/;" f class:Module +revextCallback modules/RevealedModule.hpp /^ static void revextCallback(Module* mod,const std::vector<float>&vals){}$/;" f class:RevealedModule +revinsCallback modules/RevealedModule.hpp /^ static void revinsCallback(Module* mod,const std::vector<float>& vals){}$/;" f class:RevealedModule +revnamCallback modules/RevealedModule.hpp /^ static void revnamCallback(Module* mod, $/;" f class:RevealedModule +revsurCallback modules/RevealedModule.hpp /^ static void revsurCallback(Module* mod,const std::vector<float>& vals){}$/;" f class:RevealedModule +rotationCallback modules/Module.hpp /^ static void rotationCallback(Module* mod, $/;" f class:Module +rotationCallback modules/SceneGroupModule.hpp /^ static void rotationCallback(Module* mod, $/;" f class:SceneGroupModule +run Reveal.cpp /^int Reveal::run() {$/;" f class:Reveal +run Reveal.hpp /^ int run();$/;" p class:Reveal +run osc/OscManager.hpp /^ int run();$/;" p class:OscManager +s_markerAndTime modules/DepthCamModule.hpp /^struct s_markerAndTime{$/;" s +save Reveal.cpp /^void Reveal::save(const std::string& fileName) {$/;" f class:Reveal +save Reveal.hpp /^ void save(const std::string& f);$/;" p class:Reveal +save modules/Attribute.cpp /^void Attribute::save(xmlNodePtr parentNode) {$/;" f class:Attribute +save modules/Attribute.hpp /^ void save(xmlNodePtr parentNode);$/;" p class:Attribute +save modules/GroupModule.cpp /^xmlNodePtr GroupModule::save(xmlNodePtr parentNode) {$/;" f class:GroupModule +save modules/GroupModule.hpp /^ virtual xmlNodePtr save(xmlNodePtr parentNode);$/;" p class:GroupModule +save modules/Listener.cpp /^void Listener::save(xmlNodePtr parentNode) {$/;" f class:Listener +save modules/Listener.hpp /^ virtual void save(xmlNodePtr parentNode);$/;" p class:Listener +save modules/Module.cpp /^xmlNodePtr Module::save(xmlNodePtr parentNode) {$/;" f class:Module +save modules/Module.hpp /^ virtual xmlNodePtr save(xmlNodePtr parentNode);$/;" p class:Module +save modules/RevealedPathModule.cpp /^xmlNodePtr RevealedPathModule::save(xmlNodePtr parentNode) {$/;" f class:RevealedPathModule +save modules/RevealedPathModule.hpp /^ virtual xmlNodePtr save(xmlNodePtr parentNode);$/;" p class:RevealedPathModule +saveCallback Reveal.hpp /^ static void saveCallback(Module* mod, const std::string& f) {$/;" f class:Reveal +savePnt modules/RevealedPathModule.cpp /^xmlNodePtr PathPoint::savePnt(xmlNodePtr parentNode) {$/;" f class:PathPoint +savePnt modules/RevealedPathModule.cpp /^xmlNodePtr PathPointModule::savePnt(xmlNodePtr parentNode) {$/;" f class:PathPointModule +savePnt modules/RevealedPathModule.hpp /^ virtual xmlNodePtr savePnt(xmlNodePtr parentNode);$/;" p class:PathPoint +savePnt modules/RevealedPathModule.hpp /^ virtual xmlNodePtr savePnt(xmlNodePtr parentNode);$/;" p class:PathPointModule +scaleCallback modules/Module.hpp /^ static void scaleCallback(Module* mod, $/;" f class:Module +scaleCallback modules/SceneGroupModule.hpp /^ static void scaleCallback(Module* mod, $/;" f class:SceneGroupModule +selPos modules/RevealedCutModule.cpp /^void RevealedCutModule::selPos(const int& posX, const int& posY) {$/;" f class:RevealedCutModule +selPos modules/RevealedCutModule.hpp /^ void selPos(const int& posX, const int& posY);$/;" p class:RevealedCutModule +selPosCallback modules/RevealedCutModule.hpp /^ static void selPosCallback(Module* mod, $/;" f class:RevealedCutModule +selSize modules/RevealedCutModule.cpp /^void RevealedCutModule::selSize(const int& sizeX, const int& sizeY) {$/;" f class:RevealedCutModule +selSize modules/RevealedCutModule.hpp /^ void selSize(const int& sizeX, const int& sizeY);$/;" p class:RevealedCutModule +selSizeCallback modules/RevealedCutModule.hpp /^ static void selSizeCallback(Module* mod, $/;" f class:RevealedCutModule +sendMessage osc/OscManager.cpp /^void OscManager::sendMessage(const string& id,$/;" f class:OscManager +sendMessage osc/OscManager.hpp /^ void sendMessage(const std::string& id,$/;" p class:OscManager +sendToAddr_ osc/oscPack/ip/posix/UdpSocket.cpp /^ struct sockaddr_in sendToAddr_;$/;" m class:UdpSocket::Implementation typeref:struct:UdpSocket::Implementation::sockaddr_in file: +sendToAddr_ osc/oscPack/ip/win32/UdpSocket.cpp /^ struct sockaddr_in sendToAddr_;$/;" m class:UdpSocket::Implementation typeref:struct:UdpSocket::Implementation::sockaddr_in file: +sendValuesToListeners modules/Attribute.cpp /^void Attribute::sendValuesToListeners(const int& lisID) {$/;" f class:Attribute +sendValuesToListeners modules/Attribute.hpp /^ void sendValuesToListeners(const int& lisID=-1);$/;" p class:Attribute +setAccessibility modules/Attribute.hpp /^ void setAccessibility(ACCESSIBILITY acc){m_accessibility=acc;}$/;" f class:Attribute +setAction modules/Attribute.hpp /^ void setAction() { m_actionCallback(m_module);}$/;" f class:Attribute +setActive modules/PreviewModule.hpp /^ inline void setActive(bool active) {m_active=active;}$/;" f class:PreviewModule +setActive modules/ProjectorModule.hpp /^ inline void setActive(bool active) {m_active=active;}$/;" f class:ProjectorModule +setAnimPlay modules/RevealedModule.cpp /^void RevealedModule::setAnimPlay(const bool& play) {$/;" f class:RevealedModule +setAnimPlay modules/RevealedModule.hpp /^ virtual void setAnimPlay(const bool& play){m_playing=play;}$/;" f class:RevealedLayer +setAnimPlay modules/RevealedModule.hpp /^ virtual void setAnimPlay(const bool&);$/;" p class:RevealedModule +setAnimPos modules/RevealedModule.cpp /^void RevealedLayerAnim::setAnimPos(const float& pos) {$/;" f class:RevealedLayerAnim +setAnimPos modules/RevealedModule.cpp /^void RevealedLayerVideo::setAnimPos(const float& pos) {$/;" f class:RevealedLayerVideo +setAnimPos modules/RevealedModule.cpp /^void RevealedModule::setAnimPos(const float& pos) {$/;" f class:RevealedModule +setAnimPos modules/RevealedModule.hpp /^ virtual void setAnimPos(const float& pos);$/;" p class:RevealedLayerAnim +setAnimPos modules/RevealedModule.hpp /^ virtual void setAnimPos(const float& pos);$/;" p class:RevealedLayerVideo +setAnimPos modules/RevealedModule.hpp /^ virtual void setAnimPos(const float& pos){}$/;" f class:RevealedLayer +setAnimPos modules/RevealedModule.hpp /^ virtual void setAnimPos(const float&);$/;" p class:RevealedModule +setAnimSpeed modules/RevealedModule.cpp /^void RevealedModule::setAnimSpeed(const float& speed) {$/;" f class:RevealedModule +setAnimSpeed modules/RevealedModule.hpp /^ virtual void setAnimSpeed(const float& speed){m_speed=speed;}$/;" f class:RevealedLayer +setAnimSpeed modules/RevealedModule.hpp /^ virtual void setAnimSpeed(const float&);$/;" p class:RevealedModule +setAttribute modules/Listener.hpp /^ inline virtual void setAttribute(Attribute* att){m_attribute=att;}$/;" f class:Listener +setAttribute osc/OscListener.cpp /^void OscListener::setAttribute(Attribute* att) { $/;" f class:OscListener +setAttribute osc/OscListener.hpp /^ virtual void setAttribute(Attribute* att);$/;" p class:OscListener +setBools modules/Attribute.hpp /^ void setBools(const std::vector<bool>& bools,$/;" f class:Attribute +setCalib modules/DepthCamModule.cpp /^void DepthCamModule::setCalib(const int& c) {$/;" f class:DepthCamModule +setCalib modules/DepthCamModule.hpp /^ void setCalib(const int&);$/;" p class:DepthCamModule +setCalib modules/ProjectorModule.cpp /^void ProjectorModule::setCalib(const int& c) {$/;" f class:ProjectorModule +setCalib modules/ProjectorModule.hpp /^ void setCalib(const int&);$/;" p class:ProjectorModule +setCalibMarkerPosY modules/DepthCamModule.cpp /^void DepthCamModule::setCalibMarkerPosY(const int& y) {$/;" f class:DepthCamModule +setCalibMarkerPosY modules/DepthCamModule.hpp /^ void setCalibMarkerPosY(const int&);$/;" p class:DepthCamModule +setCalibMarkerRotX modules/DepthCamModule.cpp /^void DepthCamModule::setCalibMarkerRotX(const int& x) {$/;" f class:DepthCamModule +setCalibMarkerRotX modules/DepthCamModule.hpp /^ void setCalibMarkerRotX(const int&);$/;" p class:DepthCamModule +setCalibMarkerRotY modules/DepthCamModule.cpp /^void DepthCamModule::setCalibMarkerRotY(const int& y) {$/;" f class:DepthCamModule +setCalibMarkerRotY modules/DepthCamModule.hpp /^ void setCalibMarkerRotY(const int&);$/;" p class:DepthCamModule +setCaptureBackground modules/DepthCamModule.cpp /^void DepthCamModule::setCaptureBackground(const bool& cap) {$/;" f class:DepthCamModule +setCaptureBackground modules/DepthCamModule.hpp /^ void setCaptureBackground(const bool& cap);$/;" p class:DepthCamModule +setChildID modules/Module.hpp /^ void setChildID(const unsigned int& id){m_childID=id;}$/;" f class:Module +setColor modules/RevealedModule.cpp /^void RevealedModule::setColor(const vector<float>& hsv) {$/;" f class:RevealedModule +setColor modules/RevealedModule.hpp /^ virtual void setColor(const std::vector<float>&);$/;" p class:RevealedModule +setColor modules/RevealedTextModule.cpp /^void RevealedTextModule::setColor(const vector<float>& hsv) {$/;" f class:RevealedTextModule +setColor modules/RevealedTextModule.hpp /^ virtual void setColor(const std::vector<float>& hsv);$/;" p class:RevealedTextModule +setContextHandlerID modules/ContextHandler.hpp /^ void setContextHandlerID(const int& id) {m_contextHandlerID=id;}$/;" f class:ContextHandler +setContourThresh modules/DepthCamModule.hpp /^ inline void setContourThresh(float cont) {m_contourThreshold=cont;}$/;" f class:DepthCamModule +setDepth modules/Module.hpp /^ inline void setDepth(const unsigned int& depth){m_depth=depth;}$/;" f class:Module +setDepthID modules/DepthModule.cpp /^void DepthModule::setDepthID(const unsigned int& id) {$/;" f class:DepthModule +setDepthID modules/DepthModule.hpp /^ void setDepthID(const unsigned int&);$/;" p class:DepthModule +setDimensions modules/ShapeModule.cpp /^void ShapeModule::setDimensions(const float& x, const float& y,const float& z) {$/;" f class:ShapeModule +setDimensions modules/ShapeModule.hpp /^ void setDimensions(const float&, const float&, const float&);$/;" p class:ShapeModule +setEdges modules/RevealedPathModule.cpp /^void RevealedPathModule::setEdges(const int& e) {$/;" f class:RevealedPathModule +setEdges modules/RevealedPathModule.hpp /^ void setEdges(const int& e);$/;" p class:RevealedPathModule +setEyePosition modules/PreviewModule.cpp /^void PreviewModule::setEyePosition(const float& x, $/;" f class:PreviewModule +setEyePosition modules/PreviewModule.hpp /^ void setEyePosition(const float& x, const float& y, const float& z);$/;" p class:PreviewModule +setFile modules/Attribute.hpp /^ void setFile(const std::string& f,$/;" f class:Attribute +setFilter modules/DepthCamModule.hpp /^ inline void setFilter(bool fil) {m_filter=fil;}$/;" f class:DepthCamModule +setFloats modules/Attribute.hpp /^ void setFloats(const std::vector<float>& floats, $/;" f class:Attribute +setFloatsIfChanged modules/Attribute.hpp /^ void setFloatsIfChanged(const std::vector<float>& floats) {$/;" f class:Attribute +setFontSize modules/RevealedTextModule.cpp /^void RevealedTextModule::setFontSize(const int& size) {$/;" f class:RevealedTextModule +setFontSize modules/RevealedTextModule.hpp /^ void setFontSize(const int& size);$/;" p class:RevealedTextModule +setFullName modules/Attribute.hpp /^ inline void setFullName(const std::string& fn){m_fullName=fn;}$/;" f class:Attribute +setGeomID geoms/Geometry.hpp /^ inline void setGeomID(const Reveal::GEOM_ID& id) {m_geomID=id;}$/;" f class:Geometry +setGeomID modules/GeomModule.hpp /^ virtual void setGeomID(const unsigned int& id){m_geomID=id;}$/;" f class:GeomModule +setGradientType modules/RevealedModule.cpp /^void RevealedModule::setGradientType(const std::string& type) {$/;" f class:RevealedModule +setGradientType modules/RevealedModule.hpp /^ virtual void setGradientType(const std::string&);$/;" p class:RevealedModule +setID modules/Listener.hpp /^ inline void setID(const int& id){m_listenerID=id;}$/;" f class:Listener +setImageMarkersFolder modules/DepthCamModule.cpp /^void DepthCamModule::setImageMarkersFolder(const std::string& fol) {$/;" f class:DepthCamModule +setImageMarkersFolder modules/DepthCamModule.hpp /^ virtual void setImageMarkersFolder(const std::string& f);$/;" p class:DepthCamModule +setImgFolder modules/DepthCamModule.hpp /^ void setImgFolder(const std::string& fol){m_imgFolder=fol;}$/;" f class:ImageTracker +setInside modules/RevealedModule.cpp /^void RevealedModule::setInside(const std::string& inside) {$/;" f class:RevealedModule +setInside modules/RevealedModule.hpp /^ virtual void setInside(const std::string&);$/;" p class:RevealedModule +setInsideAxes modules/RevealedModule.cpp /^void RevealedModule::setInsideAxes(const std::string& axes) {$/;" f class:RevealedModule +setInsideAxes modules/RevealedModule.hpp /^ virtual void setInsideAxes(const std::string&);$/;" p class:RevealedModule +setInts modules/Attribute.hpp /^ void setInts(const std::vector<int>& ints,$/;" f class:Attribute +setLoadable modules/Attribute.hpp /^ void setLoadable(bool loadable){m_loadable=loadable;}$/;" f class:Attribute +setLookAt modules/PreviewModule.cpp /^void PreviewModule::setLookAt(const float& x, $/;" f class:PreviewModule +setLookAt modules/PreviewModule.hpp /^ void setLookAt(const float& x, const float& y, const float& z);$/;" p class:PreviewModule +setMarkersDetectMeth modules/DepthCamModule.cpp /^void DepthCamModule::setMarkersDetectMeth(const std::string& val) {$/;" f class:DepthCamModule +setMarkersDetectMeth modules/DepthCamModule.hpp /^ void setMarkersDetectMeth(const std::string& val);$/;" p class:DepthCamModule +setMarkersDetection modules/DepthCamModule.cpp /^void DepthCamModule::setMarkersDetection(const string& val) {$/;" f class:DepthCamModule +setMarkersDetection modules/DepthCamModule.hpp /^ void setMarkersDetection(const std::string& val);$/;" p class:DepthCamModule +setMirrored modules/ProjectorModule.hpp /^ inline void setMirrored(bool m){m_mirrored=m;}$/;" f class:ProjectorModule +setMode modules/DepthCamModule.cpp /^void DepthCamModule::setMode(const std::string& mode) {$/;" f class:DepthCamModule +setMode modules/DepthCamModule.hpp /^ virtual void setMode(const std::string& mode);$/;" p class:DepthCamModule +setModel modules/ModelModule.cpp /^void ModelModule::setModel(const std::string& fileName) {$/;" f class:ModelModule +setModel modules/ModelModule.hpp /^ virtual void setModel(const std::string&);$/;" p class:ModelModule +setModelMat modules/Module.cpp /^void Module::setModelMat(const glm::mat4& mat) { $/;" f class:Module +setModelMat modules/Module.hpp /^ virtual void setModelMat(const glm::mat4& mat);$/;" p class:Module +setModelMat modules/ProjectorModule.cpp /^void ProjectorModule::setModelMat(const glm::mat4& mat) {$/;" f class:ProjectorModule +setModelMat modules/ProjectorModule.hpp /^ virtual void setModelMat(const glm::mat4& mat);$/;" p class:ProjectorModule +setModuleListObsID Reveal.hpp /^ void setModuleListObsID(const unsigned int& id){m_moduleListObsID=id;}$/;" f class:ModuleListObserver +setModuleName modules/DepthCamModule.cpp /^void DepthCamModule::setModuleName(const std::string& val) {$/;" f class:DepthCamModule +setModuleName modules/DepthCamModule.hpp /^ void setModuleName(const std::string& val);$/;" p class:DepthCamModule +setModuleName modules/Module.hpp /^ inline virtual void setModuleName(const std::string& val){setName(val);}$/;" f class:Module +setModuleName modules/ProjectorModule.cpp /^void ProjectorModule::setModuleName(const string& name) {$/;" f class:ProjectorModule +setModuleName modules/ProjectorModule.hpp /^ void setModuleName(const std::string&);$/;" p class:ProjectorModule +setName modules/Module.cpp /^void Module::setName(const std::string& name) {$/;" f class:Module +setName modules/Module.hpp /^ void setName(const std::string& val);$/;" p class:Module +setName modules/RevealedCutModule.hpp /^ void setName(const std::string& name){m_name=name;}$/;" f class:CutWindow +setParameters modules/Listener.cpp /^void Listener::setParameters(const vector<string>& params) { $/;" f class:Listener +setParameters modules/Listener.hpp /^ virtual void setParameters(const std::vector<std::string>& par);$/;" p class:Listener +setParameters osc/OscListener.cpp /^void OscListener::setParameters(const std::vector<std::string>& params) {$/;" f class:OscListener +setParameters osc/OscListener.hpp /^ virtual void setParameters(const std::vector<std::string>& par);$/;" p class:OscListener +setParent modules/Module.hpp /^ void setParent(GroupModule* groupmod){m_parent=groupmod;}$/;" f class:Module +setParentMatrix modules/Module.hpp /^ inline void setParentMatrix(const glm::mat4& mat){m_parentMat=mat;} $/;" f class:Module +setParentVisible modules/GroupModule.cpp /^void GroupModule::setParentVisible(bool pvis) {$/;" f class:GroupModule +setParentVisible modules/GroupModule.hpp /^ virtual void setParentVisible(bool pvis);$/;" p class:GroupModule +setParentVisible modules/Module.hpp /^ inline virtual void setParentVisible(bool pvis){m_parentVisible=pvis;}$/;" f class:Module +setPatternBrightness modules/ProjectorModule.cpp /^void ProjectorModule::setPatternBrightness(const int& b) {$/;" f class:ProjectorModule +setPatternBrightness modules/ProjectorModule.hpp /^ void setPatternBrightness(const int&);$/;" p class:ProjectorModule +setPatternPositionX modules/ProjectorModule.cpp /^void ProjectorModule::setPatternPositionX(const int& x) {$/;" f class:ProjectorModule +setPatternPositionX modules/ProjectorModule.hpp /^ void setPatternPositionX(const int&);$/;" p class:ProjectorModule +setPatternPositionY modules/ProjectorModule.cpp /^void ProjectorModule::setPatternPositionY(const int& y) {$/;" f class:ProjectorModule +setPatternPositionY modules/ProjectorModule.hpp /^ void setPatternPositionY(const int&);$/;" p class:ProjectorModule +setPatternSquareWidth modules/ProjectorModule.cpp /^void ProjectorModule::setPatternSquareWidth(const int& w) {$/;" f class:ProjectorModule +setPatternSquareWidth modules/ProjectorModule.hpp /^ void setPatternSquareWidth(const int&);$/;" p class:ProjectorModule +setPatternThresh modules/ProjectorModule.cpp /^void ProjectorModule::setPatternThresh(const int& x) {$/;" f class:ProjectorModule +setPatternThresh modules/ProjectorModule.hpp /^ void setPatternThresh(const int&);$/;" p class:ProjectorModule +setPosition modules/Module.cpp /^void Module::setPosition(const float& posX, $/;" f class:Module +setPosition modules/Module.hpp /^ virtual void setPosition(const float& posX, $/;" p class:Module +setProjID modules/ProjectorModule.hpp /^ inline void setProjID(const int& id){m_projID=id;}$/;" f class:ProjectorModule +setProjectionMatrix modules/ProjectorModule.cpp /^void ProjectorModule::setProjectionMatrix(const vector<float>& vals) {$/;" f class:ProjectorModule +setProjectionMatrix modules/ProjectorModule.hpp /^ void setProjectionMatrix(const std::vector<float>& vals);$/;" p class:ProjectorModule +setQuaternion modules/Module.cpp /^void Module::setQuaternion(const float& rotX, $/;" f class:Module +setQuaternion modules/Module.hpp /^ virtual void setQuaternion(const float& rotX, $/;" p class:Module +setRessourcesFolder Reveal.cpp /^void Reveal::setRessourcesFolder(const std::string& f) {$/;" f class:Reveal +setRessourcesFolder Reveal.hpp /^ void setRessourcesFolder(const std::string& f);$/;" p class:Reveal +setRevID modules/RevealedModule.hpp /^ inline void setRevID(const unsigned int& id) { $/;" f class:RevealedModule +setRevealedBy modules/Module.cpp /^void Module::setRevealedBy(const std::string& by) {$/;" f class:Module +setRevealedBy modules/Module.hpp /^ void setRevealedBy(const std::string& by);$/;" p class:Module +setRotation modules/Module.cpp /^void Module::setRotation(const float& rotX, $/;" f class:Module +setRotation modules/Module.hpp /^ virtual void setRotation(const float& rotX, $/;" p class:Module +setScale modules/Module.cpp /^void Module::setScale(const float& scaX, $/;" f class:Module +setScale modules/Module.hpp /^ virtual void setScale(const float& scaX, $/;" p class:Module +setShape modules/DepthShapeModule.cpp /^void DepthShapeModule::setShape(const std::string& shape) {$/;" f class:DepthShapeModule +setShape modules/DepthShapeModule.hpp /^ void setShape(const std::string& shape);$/;" p class:DepthShapeModule +setShape modules/RevealedShapeModule.cpp /^void RevealedShapeModule::setShape(const std::string& shape) {$/;" f class:RevealedShapeModule +setShape modules/RevealedShapeModule.hpp /^ void setShape(const std::string&);$/;" p class:RevealedShapeModule +setShape modules/ShapeModule.hpp /^ virtual void setShape(const std::string&){}$/;" f class:ShapeModule +setSpace modules/DepthCamModule.cpp /^void DepthCamModule::setSpace(SpaceModule* spa) {$/;" f class:DepthCamModule +setSpace modules/DepthCamModule.hpp /^ virtual void setSpace(SpaceModule*);$/;" p class:DepthCamModule +setSpace modules/DepthMeshModule.cpp /^void DepthMeshModule::setSpace(SpaceModule* space) {$/;" f class:DepthMeshModule +setSpace modules/DepthMeshModule.hpp /^ virtual void setSpace(SpaceModule* space);$/;" p class:DepthMeshModule +setSpace modules/DepthModule.cpp /^void DepthModule::setSpace(SpaceModule* space) { $/;" f class:DepthModule +setSpace modules/DepthModule.hpp /^ virtual void setSpace(SpaceModule* space);$/;" p class:DepthModule +setSpace modules/DepthShapeModule.cpp /^void DepthShapeModule::setSpace(SpaceModule* space) {$/;" f class:DepthShapeModule +setSpace modules/DepthShapeModule.hpp /^ virtual void setSpace(SpaceModule* space);$/;" p class:DepthShapeModule +setSpace modules/ProjectorModule.cpp /^void ProjectorModule::setSpace(SpaceModule* space) {$/;" f class:ProjectorModule +setSpace modules/ProjectorModule.hpp /^ void setSpace(SpaceModule* space);$/;" p class:ProjectorModule +setStrings modules/Attribute.hpp /^ void setStrings(const std::vector<std::string>& strings, $/;" f class:Attribute +setStringsIfChanged modules/Attribute.hpp /^ void setStringsIfChanged(const std::vector<std::string>& strings) {$/;" f class:Attribute +setSurface modules/RevealedModule.cpp /^void RevealedModule::setSurface(const std::string& surface) {$/;" f class:RevealedModule +setSurface modules/RevealedModule.hpp /^ virtual void setSurface(const std::string&);$/;" p class:RevealedModule +setSurfaceTexture modules/RevealedModule.cpp /^void RevealedModule::setSurfaceTexture(const std::string& f) {$/;" f class:RevealedModule +setSurfaceTexture modules/RevealedModule.hpp /^ virtual void setSurfaceTexture(const std::string& f);$/;" p class:RevealedModule +setSurfaceThickness modules/RevealedModule.cpp /^void RevealedModule::setSurfaceThickness(const float& surface) {$/;" f class:RevealedModule +setSurfaceThickness modules/RevealedModule.hpp /^ virtual void setSurfaceThickness(const float&);$/;" p class:RevealedModule +setText modules/RevealedTextModule.cpp /^void RevealedTextModule::setText(const std::string& text) {$/;" f class:RevealedTextModule +setText modules/RevealedTextModule.hpp /^ void setText(const std::string& text);$/;" p class:RevealedTextModule +setTexture modules/RevealedModule.cpp /^void RevealedModule::setTexture(const std::string& f) {$/;" f class:RevealedModule +setTexture modules/RevealedModule.hpp /^ virtual void setTexture(const std::string& f);$/;" p class:RevealedModule +setTextureLayersFolder modules/RevealedModule.cpp /^void RevealedModule::setTextureLayersFolder(const std::string& folder) {$/;" f class:RevealedModule +setTextureLayersFolder modules/RevealedModule.hpp /^ virtual void setTextureLayersFolder(const std::string& f);$/;" p class:RevealedModule +setTextureOffset modules/RevealedModule.cpp /^void RevealedModule::setTextureOffset(const float& x, $/;" f class:RevealedModule +setTextureOffset modules/RevealedModule.hpp /^ virtual void setTextureOffset(const float& x, $/;" p class:RevealedModule +setTextureScale modules/RevealedModule.cpp /^void RevealedModule::setTextureScale(const float& x, $/;" f class:RevealedModule +setTextureScale modules/RevealedModule.hpp /^ virtual void setTextureScale(const float& x, $/;" p class:RevealedModule +setThickness modules/RevealedPathModule.cpp /^void RevealedPathModule::setThickness(const float& t) {$/;" f class:RevealedPathModule +setThickness modules/RevealedPathModule.hpp /^ void setThickness(const float& t);$/;" p class:RevealedPathModule +setUpID modules/Module.hpp /^ inline void setUpID(const unsigned int& id){m_upID=id;}$/;" f class:Module +setViewMatrix modules/ProjectorModule.cpp /^void ProjectorModule::setViewMatrix(const vector<float>& vals) {$/;" f class:ProjectorModule +setViewMatrix modules/ProjectorModule.hpp /^ void setViewMatrix(const std::vector<float>& vals);$/;" p class:ProjectorModule +setVisibilityMask modules/Module.hpp /^ inline void setVisibilityMask(int mask){m_visibilityMask=mask;}$/;" f class:Module +setVisible modules/GroupModule.cpp /^void GroupModule::setVisible(bool vis) {$/;" f class:GroupModule +setVisible modules/GroupModule.hpp /^ virtual void setVisible(bool vis);$/;" p class:GroupModule +setVisible modules/Module.hpp /^ inline virtual void setVisible(bool vis){m_visible=vis;}$/;" f class:Module +setVisibleFrom modules/Module.cpp /^void Module::setVisibleFrom(const std::string& visibleFrom) {$/;" f class:Module +setVisibleFrom modules/Module.hpp /^ void setVisibleFrom(const std::string& visibleFrom);$/;" p class:Module +setVisibleFromList modules/Module.cpp /^void Module::setVisibleFromList(vector<string>& modVec) {$/;" f class:Module +setVisibleFromList modules/Module.hpp /^ void setVisibleFromList(std::vector<std::string>& modVec);$/;" p class:Module +setWindow modules/RevealedCutModule.cpp /^void RevealedCutModule::setWindow(const std::string& winName) {$/;" f class:RevealedCutModule +setWindow modules/RevealedCutModule.hpp /^ void setWindow(const std::string& text);$/;" p class:RevealedCutModule +setWindowDecoration modules/ProjectorModule.cpp /^void ProjectorModule::setWindowDecoration(bool d) {$/;" f class:ProjectorModule +setWindowDecoration modules/ProjectorModule.hpp /^ void setWindowDecoration(bool d);$/;" p class:ProjectorModule +setWindowDimensions modules/ProjectorModule.cpp /^void ProjectorModule::setWindowDimensions(const int& x, const int& y,$/;" f class:ProjectorModule +setWindowDimensions modules/ProjectorModule.hpp /^ void setWindowDimensions(const int& x, const int& y, $/;" p class:ProjectorModule +shapeCallback modules/ShapeModule.hpp /^ static void shapeCallback(Module* mod, $/;" f class:ShapeModule +showAliveMarkers modules/DepthCamModule.cpp /^void DepthCamModule::showAliveMarkers() {$/;" f class:DepthCamModule +showAliveMarkers modules/DepthCamModule.hpp /^ void showAliveMarkers();$/;" p class:DepthCamModule +showListeners gui/MainWindow.cpp /^void MainWindow::showListeners() {$/;" f class:MainWindow +showListeners gui/MainWindow.hpp /^ void showListeners();$/;" p class:MainWindow +size osc/oscPack/osc/OscTypes.h /^ osc_bundle_element_size_t size;$/;" m struct:osc::Blob +size osc/ringbuffer.c /^ size_t size;$/;" m struct:__anon7 file: +size osc/ringbuffer.h /^ size_t size;$/;" m struct:__anon2 +sizePtr_ osc/oscPack/osc/OscReceivedElements.h /^ const char *sizePtr_;$/;" m class:osc::ReceivedBundleElement +size_ osc/oscPack/osc/OscReceivedElements.h /^ osc_bundle_element_size_t size_;$/;" m class:osc::ReceivedPacket +size_mask osc/ringbuffer.c /^ size_t size_mask;$/;" m struct:__anon7 file: +size_mask osc/ringbuffer.h /^ size_t size_mask;$/;" m struct:__anon2 +socketListeners_ osc/oscPack/ip/posix/UdpSocket.cpp /^ std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_;$/;" m class:SocketReceiveMultiplexer::Implementation file: +socketListeners_ osc/oscPack/ip/win32/UdpSocket.cpp /^ std::vector< std::pair< PacketListener*, UdpSocket* > > socketListeners_;$/;" m class:SocketReceiveMultiplexer::Implementation file: +socket_ osc/oscPack/ip/posix/UdpSocket.cpp /^ int socket_;$/;" m class:UdpSocket::Implementation file: +socket_ osc/oscPack/ip/win32/UdpSocket.cpp /^ SOCKET socket_;$/;" m class:UdpSocket::Implementation file: +socklen_t osc/oscPack/ip/posix/UdpSocket.cpp /^typedef ssize_t socklen_t;$/;" t file: +socklen_t osc/oscPack/ip/win32/UdpSocket.cpp /^typedef int socklen_t;$/;" t file: +statAction gui/AttributeWidget.hpp /^ static void statAction(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statAddListener gui/AttributeWidget.hpp /^ static void statAddListener(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statChecks gui/AttributeWidget.hpp /^ static void statChecks(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statChoices gui/AttributeWidget.hpp /^ static void statChoices(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statFileOpen gui/AttributeWidget.hpp /^ static void statFileOpen(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statFileSave gui/AttributeWidget.hpp /^ static void statFileSave(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statFloats gui/AttributeWidget.hpp /^ static void statFloats(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statFolderOpen gui/AttributeWidget.hpp /^ static void statFolderOpen(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statInts gui/AttributeWidget.hpp /^ static void statInts(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statParams gui/ListenerWidget.hpp /^ static void statParams(Fl_Widget* w, void* f){ $/;" f class:ListenerWidget +statQuit gui/MainWindow.hpp /^ static void statQuit(Fl_Widget* w,void* f){ $/;" f class:MainWindow +statRemove gui/ListenerWidget.hpp /^ static void statRemove(Fl_Widget* w, void* f){ $/;" f class:ListenerWidget +statShowListeners gui/AttributeWidget.hpp /^ static void statShowListeners(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statStrings gui/AttributeWidget.hpp /^ static void statStrings(Fl_Widget* w, void* f){ $/;" f class:AttributeWidget +statTree gui/MainWindow.hpp /^ static void statTree(Fl_Widget* w,void* f){ $/;" f class:MainWindow +std osc/oscPack/osc/OscOutboundPacketStream.cpp /^namespace std {$/;" n file: +std osc/oscPack/osc/OscPrintReceivedElements.cpp /^namespace std {$/;" n file: +stop osc/OscManager.cpp /^void OscManager::stop() {$/;" f class:OscManager +stop osc/OscManager.hpp /^ void stop();$/;" p class:OscManager +surfaceCallback modules/RevealedModule.hpp /^ static void surfaceCallback(Module* mod, $/;" f class:RevealedModule +surfaceTextureCallback modules/RevealedModule.hpp /^ static void surfaceTextureCallback(Module* mod, const std::string& f) {$/;" f class:RevealedModule +surfaceThicknessCallback modules/RevealedModule.hpp /^ static void surfaceThicknessCallback(Module* mod, $/;" f class:RevealedModule +testDelete Reveal.cpp /^void Reveal::testDelete() {$/;" f class:Reveal +testDelete Reveal.hpp /^ void testDelete();$/;" p class:Reveal +tex modules/ModelModule.hpp /^ glm::vec2 tex;$/;" m struct:ModelModule::ModelVertex +texSize modules/RevealedModelModule.hpp /^ float texSize;$/;" m class:RevealedModelModule +textCallback modules/RevealedTextModule.hpp /^ static void textCallback(Module* mod, $/;" f class:RevealedTextModule +textureCallback modules/RevealedModule.hpp /^ static void textureCallback(Module* mod, const std::string& f) {$/;" f class:RevealedModule +textureLayersFolderCallback modules/RevealedModule.hpp /^ static void textureLayersFolderCallback(Module* mod, $/;" f class:RevealedModule +textureOffsetCallback modules/RevealedModule.hpp /^ static void textureOffsetCallback(Module* mod, $/;" f class:RevealedModule +textureScaleCallback modules/RevealedModule.hpp /^ static void textureScaleCallback(Module* mod, $/;" f class:RevealedModule +thicknessCallback modules/RevealedPathModule.hpp /^ static void thicknessCallback(Module* mod, $/;" f class:RevealedPathModule +timeLess modules/DepthCamModule.hpp /^ time_t timeLess;$/;" m struct:s_markerAndTime +timeTag osc/oscPack/osc/OscTypes.h /^ uint64 timeTag;$/;" m struct:osc::BundleInitiator +timeTag_ osc/oscPack/osc/OscReceivedElements.h /^ const char *timeTag_;$/;" m class:osc::ReceivedBundle +timerListeners_ osc/oscPack/ip/posix/UdpSocket.cpp /^ std::vector< AttachedTimerListener > timerListeners_;$/;" m class:SocketReceiveMultiplexer::Implementation file: +timerListeners_ osc/oscPack/ip/win32/UdpSocket.cpp /^ std::vector< AttachedTimerListener > timerListeners_;$/;" m class:SocketReceiveMultiplexer::Implementation file: +track modules/DepthCamModule.cpp /^void ArucoTracker::track(cv::Mat& img,$/;" f class:ArucoTracker +track modules/DepthCamModule.cpp /^void ImageTracker::track(cv::Mat& img, $/;" f class:ImageTracker +track modules/DepthCamModule.hpp /^ virtual void track(cv::Mat&,$/;" p class:Tracker +track modules/DepthCamModule.hpp /^ void track(cv::Mat&, $/;" p class:ArucoTracker +track modules/DepthCamModule.hpp /^ void track(cv::Mat&,$/;" p class:ImageTracker +typeTagPtr_ osc/oscPack/osc/OscReceivedElements.h /^ const char *typeTagPtr_;$/;" m class:osc::ReceivedMessageArgument +typeTagsBegin_ osc/oscPack/osc/OscReceivedElements.h /^ const char *typeTagsBegin_;$/;" m class:osc::ReceivedMessage +typeTagsCurrent_ osc/oscPack/osc/OscOutboundPacketStream.h /^ char *typeTagsCurrent_; \/\/ stored in reverse order$/;" m class:osc::OutboundPacketStream +typeTagsEnd_ osc/oscPack/osc/OscReceivedElements.h /^ const char *typeTagsEnd_;$/;" m class:osc::ReceivedMessage +uint32 osc/oscPack/osc/OscTypes.h /^typedef unsigned int uint32;$/;" t namespace:osc +uint32 osc/oscPack/osc/OscTypes.h /^typedef unsigned long uint32;$/;" t namespace:osc +uint64 osc/oscPack/osc/OscTypes.h /^typedef unsigned __int64 uint64;$/;" t namespace:osc +unregisterGeom Reveal.cpp /^void Reveal::unregisterGeom(Geometry* geom) {$/;" f class:Reveal +unregisterGeom Reveal.hpp /^ void unregisterGeom(Geometry* geom);$/;" p class:Reveal +unregisterGeom modules/SpaceModule.cpp /^void SpaceModule::unregisterGeom(Geometry* geom) {$/;" f class:SpaceModule +unregisterGeom modules/SpaceModule.hpp /^ void unregisterGeom(Geometry* geom);$/;" p class:SpaceModule +unregisterModule geoms/Geometry.cpp /^void Geometry::unregisterModule(GeomModule* geom) {$/;" f class:Geometry +unregisterModule geoms/Geometry.hpp /^ void unregisterModule(GeomModule*);$/;" p class:Geometry +unregisterOutputDepthCam Reveal.cpp /^void Reveal::unregisterOutputDepthCam(DepthCamModule* cam) {$/;" f class:Reveal +unregisterOutputDepthCam Reveal.hpp /^ void unregisterOutputDepthCam(DepthCamModule* cam);$/;" p class:Reveal +unregisterOutputRevealed Reveal.cpp /^void Reveal::unregisterOutputRevealed(RevealedModule* rev) {$/;" f class:Reveal +unregisterOutputRevealed Reveal.hpp /^ void unregisterOutputRevealed(RevealedModule* rev);$/;" p class:Reveal +unregisterRevealed Reveal.cpp /^void Reveal::unregisterRevealed(RevealedModule* rev) {$/;" f class:Reveal +unregisterRevealed Reveal.hpp /^ void unregisterRevealed(RevealedModule*);$/;" p class:Reveal +update Reveal.cpp /^void Reveal::update() {$/;" f class:Reveal +update Reveal.hpp /^ void update();$/;" p class:Reveal +update gui/GuiListener.cpp /^void GuiListener::update(vector<float>& floatValues, $/;" f class:GuiListener +update gui/GuiListener.hpp /^ virtual void update(std::vector<float>& floatValues, $/;" p class:GuiListener +update modules/DepthCamModule.cpp /^void DepthCamModule::update(const int& timeDiffMs) {$/;" f class:DepthCamModule +update modules/DepthCamModule.hpp /^ virtual void update(const int& timeDiffMs);$/;" p class:DepthCamModule +update modules/Listener.hpp /^ virtual void update(std::vector<float>& floatValues, $/;" p class:Listener +update modules/Module.hpp /^ virtual void update(const int& timeDiffMs){}$/;" f class:Module +update modules/RevealedCutModule.cpp /^void RevealedCutModule::update(const int& timeDiffMs) {$/;" f class:RevealedCutModule +update modules/RevealedCutModule.hpp /^ virtual void update(const int& timeDiffMs);$/;" p class:RevealedCutModule +update modules/RevealedModule.cpp /^bool RevealedLayerAnim::update(const int& timeDiffMs, const int& depth, $/;" f class:RevealedLayerAnim +update modules/RevealedModule.cpp /^bool RevealedLayerImage::update(const int& timeDiffMs, const int& depth, $/;" f class:RevealedLayerImage +update modules/RevealedModule.cpp /^bool RevealedLayerVideo::update(const int& timeDiffMs, const int& depth, $/;" f class:RevealedLayerVideo +update modules/RevealedModule.cpp /^void RevealedModule::update(const int& timeDiffMs) {$/;" f class:RevealedModule +update modules/RevealedModule.hpp /^ virtual bool update(const int& timeDiffMs, const int& depth, $/;" p class:RevealedLayer +update modules/RevealedModule.hpp /^ virtual bool update(const int& timeDiffMs, const int& depth, $/;" p class:RevealedLayerAnim +update modules/RevealedModule.hpp /^ virtual bool update(const int& timeDiffMs, const int& depth, $/;" p class:RevealedLayerImage +update modules/RevealedModule.hpp /^ virtual bool update(const int& timeDiffMs, const int& depth, $/;" p class:RevealedLayerVideo +update modules/RevealedModule.hpp /^ virtual void update(const int& timeDiffMs);$/;" p class:RevealedModule +update modules/RevealedPathModule.cpp /^void PathPointModule::update(vector<float>& floatValues,$/;" f class:PathPointModule +update modules/RevealedPathModule.hpp /^ virtual void update(std::vector<float>& floatValues, $/;" p class:PathPointModule +update osc/OscListener.cpp /^void OscListener::update(vector<float>& floatValues, $/;" f class:OscListener +update osc/OscListener.hpp /^ virtual void update(std::vector<float>& floatValues, $/;" p class:OscListener +update osc/OscManager.cpp /^void OscManager::update() {$/;" f class:OscManager +update osc/OscManager.hpp /^ void update();$/;" p class:OscManager +updateAttributeValues gui/AttributeWidget.cpp /^void AttributeWidget::updateAttributeValues(vector<float>& floatValues, $/;" f class:AttributeWidget +updateAttributeValues gui/AttributeWidget.hpp /^ void updateAttributeValues(std::vector<float>& floatValues, $/;" p class:AttributeWidget +updateCalibrationPattern modules/ProjectorModule.cpp /^void ProjectorModule::updateCalibrationPattern() {$/;" f class:ProjectorModule +updateCalibrationPattern modules/ProjectorModule.hpp /^ void updateCalibrationPattern();$/;" p class:ProjectorModule +updateDepthModules modules/SpaceModule.cpp /^void SpaceModule::updateDepthModules() {$/;" f class:SpaceModule +updateDepthModules modules/SpaceModule.hpp /^ void updateDepthModules();$/;" p class:SpaceModule +updateListenersVec modules/Attribute.cpp /^void Attribute::updateListenersVec() {$/;" f class:Attribute +updateListenersVec modules/Attribute.hpp /^ void updateListenersVec();$/;" p class:Attribute +updateModelMatrix modules/DepthCamModule.cpp /^void DepthCamModule::updateModelMatrix() {$/;" f class:DepthCamModule +updateModelMatrix modules/DepthCamModule.hpp /^ virtual void updateModelMatrix();$/;" p class:DepthCamModule +updateModelMatrix modules/DepthGroupModule.cpp /^void DepthGroupModule::updateModelMatrix() {$/;" f class:DepthGroupModule +updateModelMatrix modules/DepthGroupModule.hpp /^ virtual void updateModelMatrix();$/;" p class:DepthGroupModule +updateModelMatrix modules/DepthMeshModule.cpp /^void DepthMeshModule::updateModelMatrix() {$/;" f class:DepthMeshModule +updateModelMatrix modules/DepthMeshModule.hpp /^ virtual void updateModelMatrix();$/;" p class:DepthMeshModule +updateModelMatrix modules/DepthShapeModule.cpp /^void DepthShapeModule::updateModelMatrix() {$/;" f class:DepthShapeModule +updateModelMatrix modules/DepthShapeModule.hpp /^ virtual void updateModelMatrix();$/;" p class:DepthShapeModule +updateModelMatrix modules/GroupModule.cpp /^void GroupModule::updateModelMatrix() {$/;" f class:GroupModule +updateModelMatrix modules/GroupModule.hpp /^ virtual void updateModelMatrix();$/;" p class:GroupModule +updateModelMatrix modules/ModelModule.cpp /^void ModelModule::updateModelMatrix() {$/;" f class:ModelModule +updateModelMatrix modules/ModelModule.hpp /^ virtual void updateModelMatrix();$/;" p class:ModelModule +updateModelMatrix modules/Module.cpp /^void Module::updateModelMatrix() {$/;" f class:Module +updateModelMatrix modules/Module.hpp /^ virtual void updateModelMatrix();$/;" p class:Module +updateModelMatrix modules/ProjectorModule.cpp /^void ProjectorModule::updateModelMatrix() {$/;" f class:ProjectorModule +updateModelMatrix modules/ProjectorModule.hpp /^ void updateModelMatrix();$/;" p class:ProjectorModule +updateModelMatrix modules/RevealedPathModule.cpp /^void RevealedPathModule::updateModelMatrix() {$/;" f class:RevealedPathModule +updateModelMatrix modules/RevealedPathModule.hpp /^ void updateModelMatrix();$/;" p class:RevealedPathModule +updateModelMatrix modules/ShapeModule.cpp /^void ShapeModule::updateModelMatrix() {$/;" f class:ShapeModule +updateModelMatrix modules/ShapeModule.hpp /^ virtual void updateModelMatrix();$/;" p class:ShapeModule +updateModulesList Reveal.hpp /^ virtual void updateModulesList(const std::map<std::string, Module*>&)=0;$/;" p class:ModuleListObserver +updateModulesList modules/RevealedPathModule.cpp /^void RevealedPathModule::updateModulesList(const map<string, Module*>& mods) {$/;" f class:RevealedPathModule +updateModulesList modules/RevealedPathModule.hpp /^ virtual void updateModulesList(const std::map<std::string, Module*>&);$/;" p class:RevealedPathModule +updateNet osc/OscListener.cpp /^void OscListener::updateNet() {$/;" f class:OscListener +updateNet osc/OscListener.hpp /^ void updateNet();$/;" p class:OscListener +updateOnce modules/RevealedCutModule.cpp /^void RevealedCutModule::updateOnce(bool upOn) {$/;" f class:RevealedCutModule +updateOnce modules/RevealedCutModule.hpp /^ void updateOnce(bool);$/;" p class:RevealedCutModule +updateOnceCallback modules/RevealedCutModule.hpp /^ static void updateOnceCallback(Module* mod, $/;" f class:RevealedCutModule +updateRevealed Reveal.cpp /^void Reveal::updateRevealed() {$/;" f class:Reveal +updateRevealed Reveal.hpp /^ void updateRevealed();$/;" p class:Reveal +updateViewProjMatrix modules/PreviewModule.cpp /^void PreviewModule::updateViewProjMatrix() {$/;" f class:PreviewModule +updateViewProjMatrix modules/PreviewModule.hpp /^ void updateViewProjMatrix();$/;" p class:PreviewModule +updateViewProjMatrix modules/ProjectorModule.cpp /^void ProjectorModule::updateViewProjMatrix() {$/;" f class:ProjectorModule +updateViewProjMatrix modules/ProjectorModule.hpp /^ void updateViewProjMatrix();$/;" p class:ProjectorModule +updateVisibleFrom modules/SpaceModule.hpp /^ void updateVisibleFrom(std::vector<std::string>& modVec, $/;" p class:SpacesModule +updateWindowDims modules/ProjectorModule.cpp /^void ProjectorModule::updateWindowDims() {$/;" f class:ProjectorModule +updateWindowDims modules/ProjectorModule.hpp /^ void updateWindowDims();$/;" p class:ProjectorModule +updateWindowPos modules/ProjectorModule.cpp /^void ProjectorModule::updateWindowPos(const int& x, const int& y) {$/;" f class:ProjectorModule +updateWindowPos modules/ProjectorModule.hpp /^ void updateWindowPos(const int& x, const int& y);$/;" p class:ProjectorModule +updateWindowSize modules/ProjectorModule.cpp /^void ProjectorModule::updateWindowSize(const int& w, const int& h) {$/;" f class:ProjectorModule +updateWindowSize modules/ProjectorModule.hpp /^ void updateWindowSize(const int& w, const int& h);$/;" p class:ProjectorModule +updateWindowsList modules/RevealedCutModule.cpp /^void CutWindowsManager::updateWindowsList() {$/;" f class:CutWindowsManager +updateWindowsList modules/RevealedCutModule.hpp /^ void updateWindowsList();$/;" p class:CutWindowsManager +uploadCallback Reveal.hpp /^ static void uploadCallback(Module* mod, $/;" f class:Reveal +uploadRessource Reveal.cpp /^void Reveal::uploadRessource(const std::vector<std::string>& vf) {$/;" f class:Reveal +uploadRessource Reveal.hpp /^ void uploadRessource(const std::vector<std::string>& vf);$/;" p class:Reveal +value osc/oscPack/osc/OscTypes.h /^ const char* value;$/;" m struct:osc::Symbol +value osc/oscPack/osc/OscTypes.h /^ uint32 value;$/;" m struct:osc::MidiMessage +value osc/oscPack/osc/OscTypes.h /^ uint32 value;$/;" m struct:osc::RgbaColor +value osc/oscPack/osc/OscTypes.h /^ uint64 value;$/;" m struct:osc::TimeTag +value_ osc/oscPack/osc/OscReceivedElements.h /^ ReceivedBundleElement value_;$/;" m class:osc::ReceivedBundleElementIterator +value_ osc/oscPack/osc/OscReceivedElements.h /^ ReceivedMessageArgument value_;$/;" m class:osc::ReceivedMessageArgumentIterator +viewMatrixCallback modules/ProjectorModule.hpp /^ static void viewMatrixCallback(Module* mod, $/;" f class:ProjectorModule +visibleCallback modules/Module.hpp /^ static void visibleCallback(Module* mod, $/;" f class:Module +visibleCallback modules/SceneGroupModule.hpp /^ static void visibleCallback(Module* mod, $/;" f class:SceneGroupModule +visibleFromCallback modules/Module.hpp /^ static void visibleFromCallback(Module* mod, $/;" f class:Module +voronoiColor modules/DepthCamModule.hpp /^ cv::Scalar voronoiColor(cv::Mat mat, cv::Point2f pt);$/;" p class:DepthCamModule +what osc/oscPack/osc/OscException.h /^ virtual const char* what() const throw() { return what_; }$/;" f class:osc::Exception +what_ osc/oscPack/osc/OscException.h /^ const char *what_;$/;" m class:osc::Exception +windowCallback modules/RevealedCutModule.hpp /^ static void windowCallback(Module* mod, $/;" f class:RevealedCutModule +windowDecorationCallback modules/ProjectorModule.hpp /^ static void windowDecorationCallback(Module* mod, $/;" f class:ProjectorModule +windowDimensionsCallback modules/ProjectorModule.hpp /^ static void windowDimensionsCallback(Module* mod, $/;" f class:ProjectorModule +windowPositionCallback modules/ProjectorModule.hpp /^ static void windowPositionCallback(GLFWwindow* win, int x, int y) {$/;" f class:ProjectorModule +windowSizeCallback modules/ProjectorModule.hpp /^ static void windowSizeCallback(GLFWwindow* win, int w, int h) {$/;" f class:ProjectorModule +winsockInitialized_ osc/oscPack/ip/win32/NetworkingUtils.cpp /^static bool winsockInitialized_ = false;$/;" v file: +write_ptr osc/ringbuffer.c /^ volatile size_t write_ptr;$/;" m struct:__anon7 file: +write_ptr osc/ringbuffer.h /^ volatile size_t write_ptr;$/;" m struct:__anon2 +x modules/DepthCamModule.hpp /^ float x;$/;" m struct:s_markerAndTime +y modules/DepthCamModule.hpp /^ float y;$/;" m struct:s_markerAndTime +~ArucoTracker modules/DepthCamModule.hpp /^ ~ArucoTracker(){}$/;" f class:ArucoTracker +~Attribute modules/Attribute.cpp /^Attribute::~Attribute() {$/;" f class:Attribute +~Attribute modules/Attribute.hpp /^ ~Attribute();$/;" p class:Attribute +~AttributeWidget gui/AttributeWidget.cpp /^AttributeWidget::~AttributeWidget() {$/;" f class:AttributeWidget +~AttributeWidget gui/AttributeWidget.hpp /^ virtual ~AttributeWidget();$/;" p class:AttributeWidget +~BoxGeometry geoms/BoxGeometry.cpp /^BoxGeometry::~BoxGeometry() {}$/;" f class:BoxGeometry +~BoxGeometry geoms/BoxGeometry.hpp /^ virtual ~BoxGeometry();$/;" p class:BoxGeometry +~CamGeometry geoms/CamGeometry.cpp /^CamGeometry::~CamGeometry() {}$/;" f class:CamGeometry +~CamGeometry geoms/CamGeometry.hpp /^ virtual ~CamGeometry();$/;" p class:CamGeometry +~ConeGeometry geoms/ConeGeometry.cpp /^ConeGeometry::~ConeGeometry() {}$/;" f class:ConeGeometry +~ConeGeometry geoms/ConeGeometry.hpp /^ virtual ~ConeGeometry();$/;" p class:ConeGeometry +~CutWindow modules/RevealedCutModule.hpp /^ ~CutWindow();$/;" p class:CutWindow +~CutWindowsManager modules/RevealedCutModule.cpp /^CutWindowsManager::~CutWindowsManager() {$/;" f class:CutWindowsManager +~CutWindowsManager modules/RevealedCutModule.hpp /^ ~CutWindowsManager();$/;" p class:CutWindowsManager +~DepthCamModule modules/DepthCamModule.cpp /^DepthCamModule::~DepthCamModule() {$/;" f class:DepthCamModule +~DepthCamModule modules/DepthCamModule.hpp /^ virtual ~DepthCamModule();$/;" p class:DepthCamModule +~DepthGroupModule modules/DepthGroupModule.cpp /^DepthGroupModule::~DepthGroupModule() {$/;" f class:DepthGroupModule +~DepthGroupModule modules/DepthGroupModule.hpp /^ virtual ~DepthGroupModule();$/;" p class:DepthGroupModule +~DepthMeshModule modules/DepthMeshModule.cpp /^DepthMeshModule::~DepthMeshModule() {$/;" f class:DepthMeshModule +~DepthMeshModule modules/DepthMeshModule.hpp /^ virtual ~DepthMeshModule();$/;" p class:DepthMeshModule +~DepthModule modules/DepthModule.cpp /^DepthModule::~DepthModule() {}$/;" f class:DepthModule +~DepthModule modules/DepthModule.hpp /^ virtual ~DepthModule();$/;" p class:DepthModule +~DepthShapeModule modules/DepthShapeModule.cpp /^DepthShapeModule::~DepthShapeModule() {$/;" f class:DepthShapeModule +~DepthShapeModule modules/DepthShapeModule.hpp /^ virtual ~DepthShapeModule();$/;" p class:DepthShapeModule +~Exception osc/oscPack/osc/OscException.h /^ virtual ~Exception() throw() {}$/;" f class:osc::Exception +~GeomModule modules/GeomModule.cpp /^GeomModule::~GeomModule() {}$/;" f class:GeomModule +~GeomModule modules/GeomModule.hpp /^ virtual ~GeomModule();$/;" p class:GeomModule +~Geometry geoms/Geometry.cpp /^Geometry::~Geometry() {}$/;" f class:Geometry +~Geometry geoms/Geometry.hpp /^ virtual ~Geometry();$/;" p class:Geometry +~GroupModule modules/GroupModule.cpp /^GroupModule::~GroupModule() {}$/;" f class:GroupModule +~GroupModule modules/GroupModule.hpp /^ virtual ~GroupModule();$/;" p class:GroupModule +~GuiListener gui/GuiListener.hpp /^ virtual ~GuiListener(){}$/;" f class:GuiListener +~ImageTracker modules/DepthCamModule.hpp /^ ~ImageTracker(){}$/;" f class:ImageTracker +~Implementation osc/oscPack/ip/posix/UdpSocket.cpp /^ ~Implementation()$/;" f class:UdpSocket::Implementation +~Implementation osc/oscPack/ip/posix/UdpSocket.cpp /^ ~Implementation()$/;" f class:SocketReceiveMultiplexer::Implementation +~Implementation osc/oscPack/ip/win32/UdpSocket.cpp /^ ~Implementation()$/;" f class:UdpSocket::Implementation +~Implementation osc/oscPack/ip/win32/UdpSocket.cpp /^ ~Implementation()$/;" f class:SocketReceiveMultiplexer::Implementation +~Listener modules/Listener.hpp /^ virtual ~Listener(){}$/;" f class:Listener +~ListenerWidget gui/ListenerWidget.hpp /^ virtual ~ListenerWidget() {}$/;" f class:ListenerWidget +~MainWindow gui/MainWindow.cpp /^MainWindow::~MainWindow() {$/;" f class:MainWindow +~MainWindow gui/MainWindow.hpp /^ ~MainWindow();$/;" p class:MainWindow +~ModelModule modules/ModelModule.cpp /^ModelModule::~ModelModule() {}$/;" f class:ModelModule +~ModelModule modules/ModelModule.hpp /^ virtual ~ModelModule();$/;" p class:ModelModule +~Module modules/Module.cpp /^Module::~Module() { $/;" f class:Module +~Module modules/Module.hpp /^ virtual ~Module();$/;" p class:Module +~ModuleListObserver Reveal.hpp /^ virtual ~ModuleListObserver(){}$/;" f class:ModuleListObserver +~ModuleWidget gui/ModuleWidget.hpp /^ virtual ~ModuleWidget() {}$/;" f class:ModuleWidget +~NetworkInitializer osc/oscPack/ip/NetworkingUtils.h /^ ~NetworkInitializer();$/;" p class:NetworkInitializer +~NetworkInitializer osc/oscPack/ip/posix/NetworkingUtils.cpp /^NetworkInitializer::~NetworkInitializer() {}$/;" f class:NetworkInitializer +~NetworkInitializer osc/oscPack/ip/win32/NetworkingUtils.cpp /^NetworkInitializer::~NetworkInitializer()$/;" f class:NetworkInitializer +~OscListener osc/OscListener.hpp /^ virtual ~OscListener(){}$/;" f class:OscListener +~OscManager osc/OscManager.cpp /^OscManager::~OscManager() {}$/;" f class:OscManager +~OscManager osc/OscManager.hpp /^ ~OscManager();$/;" p class:OscManager +~OutboundPacketStream osc/oscPack/osc/OscOutboundPacketStream.cpp /^OutboundPacketStream::~OutboundPacketStream()$/;" f class:osc::OutboundPacketStream +~OutboundPacketStream osc/oscPack/osc/OscOutboundPacketStream.h /^ ~OutboundPacketStream();$/;" p class:osc::OutboundPacketStream +~PacketListener osc/oscPack/ip/PacketListener.h /^ virtual ~PacketListener() {}$/;" f class:PacketListener +~PathPointModule modules/RevealedPathModule.cpp /^PathPointModule::~PathPointModule() {$/;" f class:PathPointModule +~PathPointModule modules/RevealedPathModule.hpp /^ ~PathPointModule();$/;" p class:PathPointModule +~PreviewModule modules/PreviewModule.cpp /^PreviewModule::~PreviewModule() {}$/;" f class:PreviewModule +~PreviewModule modules/PreviewModule.hpp /^ virtual ~PreviewModule();$/;" p class:PreviewModule +~ProjectorModule modules/ProjectorModule.cpp /^ProjectorModule::~ProjectorModule() {}$/;" f class:ProjectorModule +~ProjectorModule modules/ProjectorModule.hpp /^ virtual ~ProjectorModule();$/;" p class:ProjectorModule +~QuadGeometry geoms/QuadGeometry.cpp /^QuadGeometry::~QuadGeometry() {}$/;" f class:QuadGeometry +~QuadGeometry geoms/QuadGeometry.hpp /^ virtual ~QuadGeometry();$/;" p class:QuadGeometry +~Reveal Reveal.cpp /^Reveal::~Reveal(){}$/;" f class:Reveal +~Reveal Reveal.hpp /^ ~Reveal();$/;" p class:Reveal +~RevealedCutModule modules/RevealedCutModule.cpp /^RevealedCutModule::~RevealedCutModule() {$/;" f class:RevealedCutModule +~RevealedCutModule modules/RevealedCutModule.hpp /^ virtual ~RevealedCutModule();$/;" p class:RevealedCutModule +~RevealedLayer modules/RevealedModule.hpp /^ virtual ~RevealedLayer(){}$/;" f class:RevealedLayer +~RevealedModelModule modules/RevealedModelModule.cpp /^RevealedModelModule::~RevealedModelModule() {$/;" f class:RevealedModelModule +~RevealedModelModule modules/RevealedModelModule.hpp /^ virtual ~RevealedModelModule();$/;" p class:RevealedModelModule +~RevealedModule modules/RevealedModule.cpp /^RevealedModule::~RevealedModule() {}$/;" f class:RevealedModule +~RevealedModule modules/RevealedModule.hpp /^ virtual ~RevealedModule();$/;" p class:RevealedModule +~RevealedPathModule modules/RevealedPathModule.cpp /^RevealedPathModule::~RevealedPathModule() {$/;" f class:RevealedPathModule +~RevealedPathModule modules/RevealedPathModule.hpp /^ virtual ~RevealedPathModule();$/;" p class:RevealedPathModule +~RevealedShapeModule modules/RevealedShapeModule.cpp /^RevealedShapeModule::~RevealedShapeModule() {$/;" f class:RevealedShapeModule +~RevealedShapeModule modules/RevealedShapeModule.hpp /^ virtual ~RevealedShapeModule();$/;" p class:RevealedShapeModule +~RevealedTextModule modules/RevealedTextModule.cpp /^RevealedTextModule::~RevealedTextModule() {$/;" f class:RevealedTextModule +~RevealedTextModule modules/RevealedTextModule.hpp /^ virtual ~RevealedTextModule();$/;" p class:RevealedTextModule +~RootSceneGroupModule modules/RootSceneGroupModule.hpp /^ virtual ~RootSceneGroupModule(){}$/;" f class:RootSceneGroupModule +~SceneGroupModule modules/SceneGroupModule.hpp /^ virtual ~SceneGroupModule(){}$/;" f class:SceneGroupModule +~ShapeModule modules/ShapeModule.cpp /^ShapeModule::~ShapeModule() {}$/;" f class:ShapeModule +~ShapeModule modules/ShapeModule.hpp /^ virtual ~ShapeModule();$/;" p class:ShapeModule +~SocketReceiveMultiplexer osc/oscPack/ip/UdpSocket.h /^ ~SocketReceiveMultiplexer();$/;" p class:SocketReceiveMultiplexer +~SocketReceiveMultiplexer osc/oscPack/ip/posix/UdpSocket.cpp /^SocketReceiveMultiplexer::~SocketReceiveMultiplexer()$/;" f class:SocketReceiveMultiplexer +~SocketReceiveMultiplexer osc/oscPack/ip/win32/UdpSocket.cpp /^SocketReceiveMultiplexer::~SocketReceiveMultiplexer()$/;" f class:SocketReceiveMultiplexer +~SpaceModule modules/SpaceModule.cpp /^SpaceModule::~SpaceModule() {}$/;" f class:SpaceModule +~SpaceModule modules/SpaceModule.hpp /^ virtual ~SpaceModule();$/;" p class:SpaceModule +~SphereGeometry geoms/SphereGeometry.cpp /^SphereGeometry::~SphereGeometry() {}$/;" f class:SphereGeometry +~SphereGeometry geoms/SphereGeometry.hpp /^ virtual ~SphereGeometry();$/;" p class:SphereGeometry +~TimerListener osc/oscPack/ip/TimerListener.h /^ virtual ~TimerListener() {}$/;" f class:TimerListener +~Tracker modules/DepthCamModule.hpp /^ virtual ~Tracker(){}$/;" f class:Tracker +~TubeGeometry geoms/TubeGeometry.cpp /^TubeGeometry::~TubeGeometry() {}$/;" f class:TubeGeometry +~TubeGeometry geoms/TubeGeometry.hpp /^ virtual ~TubeGeometry();$/;" p class:TubeGeometry +~UdpListeningReceiveSocket osc/oscPack/ip/UdpSocket.h /^ ~UdpListeningReceiveSocket()$/;" f class:UdpListeningReceiveSocket +~UdpSocket osc/oscPack/ip/UdpSocket.h /^ virtual ~UdpSocket();$/;" p class:UdpSocket +~UdpSocket osc/oscPack/ip/posix/UdpSocket.cpp /^UdpSocket::~UdpSocket()$/;" f class:UdpSocket +~UdpSocket osc/oscPack/ip/win32/UdpSocket.cpp /^UdpSocket::~UdpSocket()$/;" f class:UdpSocket diff --git a/src/utils/create_marker.cpp b/src/utils/create_marker.cpp new file mode 100644 index 0000000..4053742 --- /dev/null +++ b/src/utils/create_marker.cpp @@ -0,0 +1,96 @@ +/* +By downloading, copying, installing or using the software you agree to this +license. If you do not agree to this license, do not download, install, +copy or use the software. + + License Agreement + For Open Source Computer Vision Library + (3-clause BSD License) + +Copyright (C) 2013, OpenCV Foundation, all rights reserved. +Third party copyrights are property of their respective owners. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the names of the copyright holders nor the names of the contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +This software is provided by the copyright holders and contributors "as is" and +any express or implied warranties, including, but not limited to, the implied +warranties of merchantability and fitness for a particular purpose are +disclaimed. In no event shall copyright holders or contributors be liable for +any direct, indirect, incidental, special, exemplary, or consequential damages +(including, but not limited to, procurement of substitute goods or services; +loss of use, data, or profits; or business interruption) however caused +and on any theory of liability, whether in contract, strict liability, +or tort (including negligence or otherwise) arising in any way out of +the use of this software, even if advised of the possibility of such damage. +*/ + + +#include <opencv2/highgui.hpp> +#include <opencv2/aruco.hpp> + +using namespace cv; + +namespace { +const char* about = "Create an ArUco marker image"; +const char* keys = + "{@outfile |<none> | Output image }" + "{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2," + "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " + "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," + "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{id | | Marker id in the dictionary }" + "{ms | 200 | Marker size in pixels }" + "{bb | 1 | Number of bits in marker borders }" + "{si | false | show generated image }"; +} + + +int main(int argc, char *argv[]) { + CommandLineParser parser(argc, argv, keys); + parser.about(about); + + if(argc < 4) { + parser.printMessage(); + return 0; + } + + int dictionaryId = parser.get<int>("d"); + int markerId = parser.get<int>("id"); + int borderBits = parser.get<int>("bb"); + int markerSize = parser.get<int>("ms"); + bool showImage = parser.get<bool>("si"); + + String out = parser.get<String>(0); + + if(!parser.check()) { + parser.printErrors(); + return 0; + } + + Ptr<aruco::Dictionary> dictionary = + aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + + Mat markerImg; + aruco::drawMarker(dictionary, markerId, markerSize, markerImg, borderBits); + + if(showImage) { + imshow("marker", markerImg); + waitKey(0); + } + + imwrite(out, markerImg); + + return 0; +} diff --git a/waf b/waf new file mode 100755 index 0000000..ba9ee0b --- /dev/null +++ b/waf @@ -0,0 +1,173 @@ +#!/usr/bin/env python +# encoding: latin-1 +# Thomas Nagy, 2005-2018 +# +""" +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +import os, sys, inspect + +VERSION="2.0.20" +REVISION="36f5354d605298f6a89c09e0c7ef6c1d" +GIT="f1d78d12462b1fddda21584dedc83a1d269f0970" +INSTALL='' +C1='#2' +C2='#,' +C3='#%' +cwd = os.getcwd() +join = os.path.join + + +WAF='waf' +def b(x): + return x +if sys.hexversion>0x300000f: + WAF='waf3' + def b(x): + return x.encode() + +def err(m): + print(('\033[91mError: %s\033[0m' % m)) + sys.exit(1) + +def unpack_wafdir(dir, src): + f = open(src,'rb') + c = 'corrupt archive (%d)' + while 1: + line = f.readline() + if not line: err('run waf-light from a folder containing waflib') + if line == b('#==>\n'): + txt = f.readline() + if not txt: err(c % 1) + if f.readline() != b('#<==\n'): err(c % 2) + break + if not txt: err(c % 3) + txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00')) + + import shutil, tarfile + try: shutil.rmtree(dir) + except OSError: pass + try: + for x in ('Tools', 'extras'): + os.makedirs(join(dir, 'waflib', x)) + except OSError: + err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir) + + os.chdir(dir) + tmp = 't.bz2' + t = open(tmp,'wb') + try: t.write(txt) + finally: t.close() + + try: + t = tarfile.open(tmp) + except: + try: + os.system('bunzip2 t.bz2') + t = tarfile.open('t') + tmp = 't' + except: + os.chdir(cwd) + try: shutil.rmtree(dir) + except OSError: pass + err("Waf cannot be unpacked, check that bzip2 support is present") + + try: + for x in t: t.extract(x) + finally: + t.close() + + for x in ('Tools', 'extras'): + os.chmod(join('waflib',x), 493) + + if sys.hexversion<0x300000f: + sys.path = [join(dir, 'waflib')] + sys.path + import fixpy2 + fixpy2.fixdir(dir) + + os.remove(tmp) + os.chdir(cwd) + + try: dir = unicode(dir, 'mbcs') + except: pass + try: + from ctypes import windll + windll.kernel32.SetFileAttributesW(dir, 2) + except: + pass + +def test(dir): + try: + os.stat(join(dir, 'waflib')) + return os.path.abspath(dir) + except OSError: + pass + +def find_lib(): + src = os.path.abspath(inspect.getfile(inspect.getmodule(err))) + base, name = os.path.split(src) + + #devs use $WAFDIR + w=test(os.environ.get('WAFDIR', '')) + if w: return w + + #waf-light + if name.endswith('waf-light'): + w = test(base) + if w: return w + for dir in sys.path: + if test(dir): + return dir + err('waf-light requires waflib -> export WAFDIR=/folder') + + dirname = '%s-%s-%s' % (WAF, VERSION, REVISION) + for i in (INSTALL,'/usr','/usr/local','/opt'): + w = test(i + '/lib/' + dirname) + if w: return w + + #waf-local + dir = join(base, (sys.platform != 'win32' and '.' or '') + dirname) + w = test(dir) + if w: return w + + #unpack + unpack_wafdir(dir, src) + return dir + +wafdir = find_lib() +sys.path.insert(0, wafdir) + +if __name__ == '__main__': + + from waflib import Scripting + Scripting.waf_entry_point(cwd, VERSION, wafdir) + +#==> +#BZh91AY&SY:DvE]����DP�����������m�(¬#%0�E0m�b��z`p#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%#%��_O^m��f���w���e*hi�vӵ}�;X�ݫ���ͲKW�ݳ}�ݶ��tw+������{\3�f���=��<RQ�n�w�x[��N�pq{�l�����A����-�6��h�d�44m�}{�n��A���;��0;��ޮm���#%#%��;#%�z:p�AG�PvmͰtiN冝͠v��w3Kkj#%Q��W:��}����i�̀�T�6�5���T�R(���q E$B�QA�:j(zҕVm:��CϾ������^�훖e�̪�*Tm�uĮ�wc�sɭ�#%Y�������v�l�*�������v�{����{�}�������Svz�|��7�8�n^��F��Eg��@��P��5�����t�=���w���74ðiJ�x��fl�ȩ'{���@TT#2U$��(��T��˝�vޝ��z�>�m�i���;�Z��l����:�s��#2w�ٛ�;y�hW���������o�W��=}㶯�p��#2h#2���so����\�_X�<�����v�9���l�wۇ���m�m$����[�����r�>�w|�]�jSL���Y�@_a��c�l���j��n�r�:|�R�nݕ`�����n�l�����ݙ˭���{.�}����}r�=��i朝꺹���#%=�=^oO^�����hL:�ED�URKB����w@n!&e�v��o�{�.����1,gvl�m�]���U9ө���d��{ٚ4 ��m��x#%ݎ�#%#%o���W.'w�ﳻ���]����U<f��]6��-Ce�g^�{���lUQ��ڜ�7ێ��f�/����kx*��J�4��n�����x�e{(z�맷�iَo����f��n���l^8���w����ӻ��>;�/r�ݻ��}�hlƀ}�z����Z��[nwA���y�Η���9���Yש�v{@6z�#2�}w�i^��t����p:��h�.0�i�o^�O�����u��Z���a{����|�+�C�{��A��u����yֻa�.� �:s˻���kyҀ�C����#%#��Wn���g��R��@���������wW��ݝ���6�ê�W5�˷p7wH�E˝�ZnΩ5ݷOw�����㩛=w��%�+�Q�ǫ_W�x�Ϟӹ��O|Bك&�����ټ���:�f�z������u����ݶ�����7}K�x3淍�i�#%� h#%��#, �C&��!�#2<����#%�jSj{E6���!&Aa4�EO4��i��hژ�h#%#%#%#%#%#%�DAh �MLL�j3T�'�O�L��jz���44~�# �#%#%#%$�JH�F�4 ���mO"����i�#%hP#%ѡ��#%#%h#%#%#%D��#% #%�SЙM&F�&#,Bb�#%#%#%#%$�Dh#%�M@%?$=Q�I���<P#%�#%�#%�����U�q���UW*��ݿ����ѕ>5Zu!J$�",!2D�"#%H#%���A�?O��������.��Wb��L�âԬ����.Cy�5��fR��>g�R���� 7a��3�l#%��t��guD�D�7+O�W4]\=cl�0���I��b��9k��l����[~�(�AR R1B@��(Ȃ1�)"��#%�#2p���P��9`I(��C"��9E,DF�#%HD��"��E �@*��#%�#%rBfL����CL�d@M$Rj6�35�25)F�Sm&��4����TlњK&�#D�B�R&Қ #%6�KbʛF���-�(JYiM-�!e�6h&�31�I�F�d�#,)�E ��%a��-#Jm�l�m6��VѦbK�3!4D�2ɶ�m4�Ԕl����Z�l͔��&b(*"�i���E2(�6�B��#h��h��B��IS�*"#2��`!A"$��Ȍ�6�L�ib �ٚ$LR��3 ����H���1�k&�ƋL*E�,�$h�SLbJL�2�4d�ѓ#2��"QI�#2lh�,E2��E3��Hf�I�hfl�&�$���X$���DIi(���*!$J4H�`��!���F(L����3cF���ԑ$�"қ HD�d� $Ŗe��%e26"f�ȊQ�#0L�i�!R�f��Y �M#,�DjVK$lQ(�&E4�MH�f�Ɠ��RK(�j4��mM4Q5�,��YŒ�"h&�H�3 �J��be ��I���#�He��l�*fj�Q�RؔD̆�S�FlhP����(�Rd�d�lc%M#S4X�I#2L�#2YY��V"0DQ%&��4̂��Q����E��)IM��Ɍ��B�$b�e$)E���LI&��4��"E#,#`LF4*4�"m����Bi2�E�"d,ȂSd�1J"�L���66�X�K&2��-��)d1���aA�,j,�%F"Ԧ�#2-L4$̤�d���"�hҘ��BY2�%V��тe ��2��QI3""����h��FP�YSf��2��Q�#2)��4�F����;k���a�͢�lVƶ*6L�4�R��44����F�5Y���c(�)��$["���-��(Ĥ��ڊBѓL&��,,jAL��&L�6��eZF��(El�dU*�J�Sf�c3VƋ"+d�+"T�)����R��"�#@d�mE�k,Ii���*��Z2TUd�J6��TT�F�M2Fر�X�F�-X�I�T� E �4c!i�iZ[lh�bk�H���-j��e��Be3R�MT�HD�iH��Vm�R�J����XV����RșKSSF�-�%2��,���![,� ��D��b�4��!��-�T%��KQY&�6L�J,�&��l�#,"+,�E1��J�l�4AE��$&Fm6�F6��S��cE%bHɨ,F$6Bh$���D�ȥ,�j���24i1��3d��Z2E�Q��fRIF@ѐ�1e5��a��#�d��$Ya#22Z(h,R�4h�)S))e+0�X�4Y#bԋQ�6kFh���JRl4�KfRZ�FBL�1�i��%IRe#2*SLl���%)��f4�M��h��4Ҍ���dF�3D��$�(��*�F� k4�%14���Z-�Tj5b��Fe��a��B��#c�أ`KAY�Ő̢#,����K)*dE�mƨ�h�2�QAb� 5&��0�,#�(mch4��d(�D�T�-F��#)[dT���4�",�"��-J)�D�6%2�Dj���E�%Fх1f�[&Jŵ��%e6Ȗɱ�4J�S �TX@�lll�l�$�b6��I� ՙ0h!Q�6f��SX�2�k24�4�QAQD�jJŲ�X�1h�F�IZ�-,�m�Z-QV2�m&�D�6Ƥ��"�"����R#��$�h����m���d։�R-�Dlld���U4�Fѱ��-�3J!,�V%��b�*6�6�*)JҌ�B3HAeF�IQ��řREi+bɶRehѬCLZ)1�hն�j�"eB�bJ#$4hئ�mL1�m�l[b�5mֲ�T��[)d�SSl��&��4eDh��IE�Y�5&f�*"�#2�1$�I2##���[E�m�����'�4�e&o7�E�g�5�a(�jNW�������{�*���e�h4i}GD��bmc�����#,H�d���2'���,�q:dPCo�՝���"P`�tq�K႒A��{�~��kD��UH�_�0��u��J���/e�+(U"/��a�{���J��q���q�΅s�P���٫��9'|��j�%��N(m��b#�5�f�ID)#1�$v�l��1�#,�Ѣ:8Ǝ�'y�!1�r�OJ�Kƹg;�_�����3����j��M^,�2�ٍ.e�)���D��lK]���1�c3�(��λP��ܲ3znh�l�AL^,0����q��۲�����{nf��g��s_&��<r��}�R[�R~_�u�����ޙ��ulE�#2m#2E���J��hI���.c`cCby��< �x��ː?�0�B��(aB!�ұ^'���ٹ�����RSo״1�#%�� ֭n�,3ۼ��w���,���m���$�؞�%�X{��G�O5�����ܹ�7Z�a�Y���u�L���a��ɖ"3lÖ7UU� 뺐�˗D#%��m9��q�k�s��"0ޥ]s{��5]r���nQҹs%u�$�s#��^6�Wu�w��u�+��O{����43�leƉ�e�#2�(�D�~�F4��K��ٙ#,("W�4Rn�M0Z�@G���d���К� )p3ƾ�@�:?-7�ly�27DU�;���6 �����/m��I���Z�QB����,�>�)�ruj�oQ��#,��i�aCG/���5 �y�u혬�?�|YH)ɨ�>~��9�|��ݭӓ_J�,�x�r��<��־K����#,��̤l�j�蟺������8���T�)b#��}��:��&���,�H_�Z��m<�_s(W�O��,���j[�-��E�6(����2b���_����~n�$7�m�Z��*��N��P�-#2�A�@��*�{iX<�Z�W�;(��8��QQF��MF�S$?���b��c!�+Ƃ�+����;3DR5A)�AX��o�0���bSQI��ܮ�uV�i%"��@X�'+��&D�)J���墶/]���W�)VJ��ܱh��-����E �~����{�tu�lj6M�g�o�K}���>��a���o�`4��E��h;q�5C�2��bf��V}�&A�5����(dk&�}]�|_:9j罗���",5m��)J����D��C���hzQ���QL��UiN�-wլ�����Х�²���������S�E#2l�QMZD1�>��2Z~��Gv�Ŷ-5m�e��S���D+�b��N�<�kH](��#2<*�o�/�����6ŇD� �˽�2��q������z�r�W~`c� su�$ߜR��#,Xe�xY`E#%F#�,b4��]���w��M�W)�����/��}�Gy��c��-SL��Ơ���84�������n~(�=,��s���z 5�I4#,�ɕ�!�7���\�crF��D��a�e� �#,�n#��_�M�cR鰁G�.]��Q�LR1���9�©ԧJ�#2˜�(��>ԥS�?_;珛�H�d��~�?]��Gĺ�c��i��ۖ����Ɣ���M�����Z����lL�C��mJ-��9Rr3T��HŔ/C�H��a�ygL1��N�8�r��\�~�^u{��x��\H�p�6熴zm�*�'ک�1��a�?>��*�F�������Z�4�&�Q��.�S2�k��6��x�uq�C�6:D}_&��#ZN�]��ed��#F��T�l�Kj��λaш�p?,�0#+��G��)�9�4�=Fj/nvfg����=�u��8Ծ�(S���z^�$#m���Z�<����kO�3�j�0V�(G}���#,����֫����#[�m�=@�.�.5�����r��u�m������ţ\��]}6��y��!$�"���=yR���`�M�a�~LѸn��7|��L���(H� �orj��]�۫��eU�(��q���c�T���� @^�ǡh��ӻ��+�kn5��T^�cm�Ŷ�H�q�����������TJNm��N��S#Y����6CTEM���'���家��RK*�ɐ�*V�_kB�#2#,����u뺟Cq����kHL�(S#,��~-UKTW����&|��n����[O���x꒾梾�b[y'�Q�#2(��3��A?����-��O��r��L�ϩ�\�(/�r�H���6���ઽ���e� �z�`@bX+Ä�;\}�e2��`I�i�^PO�-n�X#�~���\m���ϕmr}i���#,D��V��K�*^�L���7��u����Xv�i� ��:;��ߊ�&�������(���3q����c�##2Nr�k��nS繣�tuO�~��$_��抠�s߾4?�Zu>�v.��^1F�-�W���mv�#2c��i��M��v��]}<�{s��� ����2��� �TS�2�띜]�0�;�C���if�DMk�?A�P�0/�#V����Ϛ������-���%�x^��DES#2�����UHx3s0)S�J�:�x�J��ط<o.���fHg�+Cm��꩷�<��#,tz�8�5�`B�������u�(��`��n2_��fR�Db��:q�����������,P�:����e(+vteFW=u�����ƶ& �:F���c�~0Bi�y*���'���]L�u����g�e���6i�wd~4�����,��v�"�G��c�����gd$���rkh���z���^��;����[(/��c#��M��*�]]Ǜ�T�4Fz+j+g1U 1�!Q��Y�>�P�*�#,ʢ2,S�\&�X�@j�9ԡ�#%�j������M�4O|��ւ�$������p^C��T�a�#���ڇ�3�ç�?N6�N������E��K�)'.:��o�1���>>!�?�?c�7�n&��+5�ʎ6Pe��7Ωf����y��-�_5�vʍ�G��/>S��=�:%o.6�oχ1����q�%��µo�De��|3ZξWX1��Ǘ���z���s�]�('�Ҏayz��q�+��L�G�k�|��g��+0=�`�MF0T٧ܠĂ&�w"��}�ֳg��i�T���F��_?��Q�,mo�m�ѣ���ž%�C{���ܭvჿ�R�f�(YUG\��J��A�}������Y������tj@K��G����9*��1�Z�c�eC��]3�!�j���j+�3�Dh��TT��O*e8T!�_% ���9D�9өu뢇��2m�u�V��FzP�L^o�c��28mDzX��-��8���<+��f�J��������q�ú_W#,�$�Uh�c���1;����x�< ��փܛ��E''Ni<�X�D}S�*��q��l�S�y �@iso�Hm2L�M���d{�M�yb�Z�0P�W�j^��_f#J<Y�*1b,�.���*�',cgUI�c��1���T��*2��b�lX�, x�Y��G������b��Y,H����S&B����SR��*���2N��V�o�;2���(7C��v�����3�1.�m����+�Qe�yB>�~�m}6�XŇ��T�P���ݘǒ7�b�n��b�#��C7mD��?���V]6k)0�iFM�����A`�DY�O^�;�+�8W��l���X6�ɠn���`+���P�Gk�~Y斪}�͘�䖖ǘgjϜ�r�PLoQa6���S��q 6@,|7�����ӳ��v@�흒�����-��G:�{��H~��!�pL�F#(KB���*c*kma�n*���Q��N�L�^ph�&�����'�ӦK<�q֡����'�4V�D�O f8Fl���U����l�O�D�T&AN�7?�hA�0�ψf���k=�u�B�L������5����s�_���-"Q�D�@��v�=`�6�{m����Ѱ�9��VN#,��A�O�kM3���2<�j��5�[*Y�"��Pʍf���ј�-]�=.�@�DfjJ�%U��#y#%�m���){��r)q�u��Yy��j�X� kLF�o��w������c�����x���lI>2��\�#���{�S�#%b�mꋀ��z�G?����Q��)�@Pve�����/��F���z(T 9h�����_��ܣ<Ti>}+_T�y�'4��)�Nq%울�(�8��L��7��� ����*;y�T�6k����a�uuBC5�<��3�o��f�}���i��͔0;����kv��2C8�����e���-�m7Cl�Ŭ���pNm~��ҍ�*se�ܙL3��8�|���n�#%������}F0��#%����'E<���Ѝ�`4��*�a�}�?^���ʍ#,0q��m�|42eo�m���>�U�˦.��d�}&ݪ�%�c��B��=��<����w?�Eң�F-U��ȳܠD������,���(�i���5#,VG����$���Z�>ˬ;q�������x��Ҩ���d��8�����p'y:�G;��x��rO$��0�XY+iB�q�ɽ��������Ɛ�������-�4�D�����.[��J :��W��j4.�y�&�iu���|Lh��_s�r2N��÷���aÌ4S���Ɖ��V��{�6@�`�ҏ4�1��������,�<:A-tl�@�N�,��MCJ�/,�8���w�����:]Ue�*�-':&º�{v{h��r*����J<�o���!a�p�:x�e��;�l����Q��({��˵m�"�;<i#%����j"�(I�g(N�X�ص�+u���(}�;M�N���PY��vf�EG��䂎�mn/>75�]��Z2�_��[7E�Dy�[�ڊ#2�(Es���:h;E�l݂ˎ�Æu��$��K��F�V`�R6��9�X}ͻB�����-�R�A���#%$Q�k���G��B7��r���)��9�|y|0e6{�������͢�>(�:�����K��BBū*`��#,�[�;���>�#,�)#�@��U~yܐ�f�H�H��TE��l�Q4����q�N\���v��#L�l�܃B�T`�)6�4<V:w�wA�&�訜�`6_H���eG-/������iW����f��Qް)^tq�����ON�ף��틀�r��4�s�ex}�Jv��ְK�z>�5a;���kΣ?]r���E�ځrQ�\���Ǡ0x�v��k8#%��a�xe��?-�3��z��zM)�CKv����Qc�L��r9TbO|ӦQ/���k��D[鷏�3z3�+@�4�C��1`�Å1� ���,�Q�[��e�U�"p#2�A�X����sk6�P�#%�f����Ư]���X8C��Aݼj��mk���S���2���_�b5��c�n��Ff�8%_������o�;2�����//G){�#I��.W��Y��e�= z�=v�(q̍�;���XU~D8��Y�<xp��6p�#% �ݤ$�A7���p @ @H��K�5�k��9����]UG�ZY"E6I#��o*9�/�Q�?Ju��k�m-�6�<>-^__���m@'�(��*�z�|G��_٫[�l1�1��6C��;�7���Pq9�0DR #%����_�s��O"N{�~����{q�u�P��6�!�#2"#,�Mq�#%�YG�p�j���f� neEXQ��.c�mظp��·�$����2(�A�J���~��G� )�"���/Tj� �9�%�]~g7u:A��`�#%A�o������r�0� �Fj�Y.@�*"K�=�X��3 ��'�Rgb#���Uz��F5��^1��D����&c#%%;#%1��o��sʰ���?�Ra����~�ᦳ>�����O�f'͏�b��*�bF߹�� <�]����R�ᱵL�Y|S�܆(H�>�ul<��^~�_� 2X�H;��#%X�kȵxz˦���.x��9�}:����@a��2�ٿ6�4����j]���:;����>���;?v`0�)���f���m���(�P}���Q�+��~7�w����(=��co>{:�1g����_���f� ��0�;��J������ҳ&P��_�����z�XɲQP�=��Ǘ�uߢp�d�~}���gS�w�>�XB�<�I�M�mG���ub���Oz���}�'^͡c��7B��W��f�r�\�pw�_`����E�T�֓q֞����ii5$D�?��ٜ�[�+Y�,2#^�e4���V@�f붼8�P,�9UaGm���%�� ���@�7k��"�%y�z�x������2�J��P��z�H�����͘�PaLYIJ�7MC�*���⮈����*�cP��߯Vs�s������$���j�����s��.a'���c��Ɂ00��Sf����Ւ`zkl�ES�±al�����B�c��_F�g��,[3q1?&�HuH��M��X����ϛ��)��>��ܘ�#,a��O�#,ֽr�G(z� mԜ��0����Tu���D�#,���^vU(�(7��q�TZ���d���q@!U� ��w�z;�/�7�x��X��� �!!�#�6��u�;(JH��on���|Y5�C������wJ��2s#,V�U�Af��L��R#%bM|3���C�:������V��#%�tn�В�����6�R2����&���k*�(c�~�ͽ��ƄNI�w�SnqM�L�Yj�#%���#,$��^��3����nq�6%U4Ѳ������0Dj��#,��|��.��İ:�xM֝��RI|�c��紳*�.7�%^tB:���z���3�|��ФF�Q����j�]5e�%.�T���q����3+8Z�ͥ=����VGDw�VIB�w��q�H�:���W��#,�}_O��,v8��#)&�#,�~��.$�ڡM���j�Q��� ���5���p�v��ۅm}M��s��AB)2MB���L ����;=��l���ïe��P�#2�h�"#_ �z����3��2&�B�х5�6��ܦ2,,���|ز�R�"�Q��Y�y`A��+��:�4�{��Z�����͊ktҟ�00�yk�W�f»�c*DXEY'�cLmX�p���]��6/g���� � I��ա!"D-;��p!�}��Gȸ�7�Qor��q#,ِ/���3�G �e��A��� b@1@00��#%��!���)Ƶ��"]!��hhRv�*>�����@z���Q�NU�H���ڭ$�ԥ���*r��-,P�G�����;.�sw�=.�w��L3�0ɞ�j����1��s��D��μ�r����(ݽ��!H��>����^k��R�;#2(=x�q���#Ig�x�4�hV�KD"e��͜�=Iȼ�]7>�=x��)���ѽS�ېݝp�tt'皋��:TP�Q����C3�(ҁ���#,Plu�ŋ��kq��̱�ƈp��#1s��B�s�n��C�g,[���#2]�P3y �Q�'��� c�z��cv��!#�V:;�ͽ�:y���G�6He��;>F�����pIm�����O8�,�}YE�y{^�I�fxO�pL��G����?q���DYP���5`!/�2�^�@�{��OZ�c�\ff��W=��=Mn���k��!?"�;�A8��x���=�#2͖2],P�z��w�e������h���r�Q�������=��ÿM4��6����^�Ѹ�.`b��#Bm��!I �5LUaL`�ѕF�g���0iP���"�H`b#%�:���[�5ϗ�}q&���k1��F�H�v�������q�(��$�t���c�+��,�e�7�#e��R�R�x}��q�d��b.6Lj/��77j^&���*R˱�!}9�!�8TT)�h7�xɐ��#2x!���1BD����}�5���%��CSZ�\#,nVٮ~=��˴.��)ݡA�H���;U��M�S��h��_I�KN��W��'��е�[l3�]y��a��3^}�³��x�5��8;x�Έ�2S+���Ѧ��䩋^h�3�'Ff����cu��T74�6L�V�B�hx��T&�ɇ��d�5PeA��[0�aX�@���H�̈3#%�Z\��,qbBf�Y`@�#24`�����i���K���ؾ]���#2H(l�SF*K�t��W�W������"�X�2ѷ�J6ҭ#,��i�������U0�b�l��IL�P0�#2B! 0 3�����n�v3;������ź�~�`+Ef,Uq0�X3J���Z(�5`�|]�mH!��U#W�)|����@z�DK@�v�v �[F ��l�'��7��w�tD�ქ�{c^# D�#,�ߣP�\{������7`��-���Hz���<���B�A������;�V��H3���m7P!fG�*]%�m���)b�K�oS������r���ș��WZ�8�c@�|���:_i%�I�l���T�`��=��ٿU��BB�_�h1�Fx^9Ko��9ø>�s��4�Q�����'ML�'#,&���H��vԝ� i;|��[����a�#���<u��csݗM��@j�����I$�����m�j��?H���p@i�f�Yy#,m �RQ��(00�Z���.��a��p{���a�}�TJ��u<�G����Ejܡ����ֈ�%�#d�{O�9��@��(���4���#u���ep�*8'mJ��U'����M�w�r��������^tN���~�-�%#%�#,�2!�Gy;ɫ"+ ѧJf� zR�Y%�2�h����:��6�R(�H��y�*I��[����MH��+J��v�#2��j�7�lB��mEhұdt(�h�1bfZT�q�����;�F��Ǧa�A��!�b�K�#,��}�^�טq�%Zl�v�g��#2Bc5h#,��e35ҷͩ�#�pPҸF��.����4vM�s�ď����r��\d��\l�^�&��ʑtG�G-9�3O�G�S(����^V3��w�I3��"�]e�w#,r�u��˽N������p#f���z܈�ע��#�#,�]C��k�ޣ�����z�)aH����n�V��r�uƟ�&G���C%9ȳ�q���C��jm�}�(P�r���E)"ԅ5��vyrn.#,lGHR囋�E�}�e㺇<��g�~m�q#֧i�>NcUGE��ۏ�m�dǐ&#,<� a0NϊsfEۉ����b-M������4�Y,Ħܨ҇Z�EX4��E\�O7�A�,��@�GnP�:�O�cJ��:7Zf6O+�&�H-�v��e���.�����1�yc@����f��3���U�R�n11���jDd �~^R��*�����q}/l�t��:��'��V�C�#27��r�2�����c�T��f#,��B�Z��:�3�'V;��X ��ʴmz���xۍ�Ϥ>�^�N��]#ӑ��Ks8f:�F�!�y��Sh�iN�8��E����t�F�m�Z-�m�i!��D=hh����U��a#2]��ʝ�C��0�w�m�y�f֡����+Pj��i�+� �6�l&������z�xi#%� %#%&�.e�%n�tX{s�U�?so��p@~(M���kk�����B��u.�u(p�MѠ�bh3�����p�t���Af�����R�9'�"��Q�;�9�<6�r����j�#2j+�ۋ�~�N�j���3bJ�V#2&�� ��D�'[�.d�����Y%���y����'�TWfB�����(&es�y�ù�C�b�t�.K�4w�H���1Yw�|>��]�#,�P��|����/յ�+,��7=�u�]:��x�����}�}S��0���<�ͧ����:+]�� �~�`"1��|Z�{�Ԭ���$#��H��`�w��z4I�K��w[��z:������6��1e��1�TW����1A��~��<%�(�h��C���)Te���W�8��Sn���[-I[r��}�ů�P�M�#%&/��ڲ�I������O Ί @� K�w��t+�=���x����tdz�+�ǂ~,�bLO혩R*���g���E3jK&�1�*X�_��bh�b�뗣��E�w:�Ү[���%#2���>Sp������� ���L#2���?�,���]Zm�`bP��}�y��jw][�W-y��ؚ����j���Qr�h����J@��ϧ��N��O����Y��)���k[�F��맟���Ž�J:3#�'$!���A�AVD6ޒF��-W�kW��(��a�����C�p�����M���K0��5@�T�%�M+����G���8��?�U;pW�� q�ۜ����-X}Q�_�?���Ջ���3K�uc�B�� s��ճ�����Z�#,���;`"�nx�iepz8y�.'#%����B�C��h#2V�-9�[�]�hl��!���$<곸�p�P��p�#2Z�AU��\o���O揀J�#2(���&��T#8z��c� y���eo��?���N�&*�{Q?:�6���Ҋ�B���&�`�?�ٷ?��¡@�0Rq�A�#|����t�j��y�A�]�~��o����?O�+��_'$Ο耴9m?���2��#,s�w����<��r���t��q��� n�O�l�m9�����w+��ϽG@R-�`���"�:D&H�:�����Ԭ��b�G���L��D�Omп��G�=��7���,k���=~x��˴�r�n��>(��I�R6���u~��io#2�a��{ ��g�g��N2�-YS���rC�(#2����>0���FoZR�%ZX|i�����`���Z�|I")�X�#,���;C��}4��4�Pd�:/��p.Q���~9�i#,xR_ �Ź��H�y(�>����9���?Q��O�3�ϥc�'��У�0,i��a���w�<w �H�T����O�3r��$s#��Ξ~��#%ؽ�Y�X7�D�N�$�o��������3�ӊ���"���q��|m�X���n�?$�5;�p��j*����B�''5=M����THO�eCޡ�R�3M������٩u���J�B�}l��?���~V�&-��1!1�! k� �P>2H�Dh��)���:�So��G�gH��'m�����Z]�#,��\�)�bI��|��Q\F�Z �� �Hl}zM=~0�9�[�����ݵ�#�<#,,����F��A9�į�X��TCi���Z�V3X�����~n�\��"�>#%>r�:kMO;\�ŝv}�r��wvO;�xr�?�F�F�����7�C���.0�� )�.A ~��p�x���?��<ӯ]�7��[dä<������������/�~������yu�U����:}T�Rk���,�b?5}m���W��#O�cIKk���\����["�������#���}�?E�{����~ߎ\��!k����~8ED�U���?]�R��>n���&��#28�pboٟ�C��v诹ZSy��j��G���k�����m�y�垟������e�E��2wg�S��=<����N�q�x=��� !������}�� s$���?�n�utc����e����ߏ���9��!-2���Ɉ��l���u�����q�{^�1����z<�f���v�_5i����#,��Ւrã�������g�R=o��ٷLn�����倶��CΕn�օ�.�j�K@,m������5���m�@�ȥ(�}��J�y4�a����M4F��0����F%�.lA�>2.s���?��9�Q������'q�r��||9a����wk&�c��b%��p�ڮ�������١��Pà��k'w����4���Y��UqI|:��zx��D���Xi�k�1����k|G#�ef��u��{�7�b��]�9��!6���������G�{�|����q�q;�5��ÿlm�Cj*�����z<����K�Z��l-�;���J�p����H`~���RC%���^e��TV��i���'USV�o�tv�[��:Dr����m��E߹D�W�s�WϿW��t�/m���؞_����z}���״��1���Ю�]�z/�ǵ�����i��s�0�/f�����.!A�:�}�^9��va��W��u0٦K�[Gͯ��g�a����'T��3���_���w^2lS��7�|���~���ў�p�C"�%#%���8W���U��gU��nx'��������=�6V�PL��;�9��5���Tz5���Њ<��,�s�t#,�M.�+�SS���r��Cbt���������Q�u���=�9�wY��寮-��������~����_�6�����Т��t�z���ի�A����~��ʞ~���_�����m����}�� }��f���;n��=O�w}��>��ˌA�έ�-]�&��<�.�H����A�Ph����r�<~/�}���]����=��#�y�����.[�Sl��3˾�;#%���n�#%P����$��a�X�:۳��#2u[��W7#,#���ջ����F�Q�Ҝ9����l��n0�|�:�>�:S���A��/�-#2@���G6� {���OĖ�x�y8�nP�V�Q�������c��ڂ�#2`�ə��+����Ժ�%7���Ɇvy�������o?O�����_��]�>k;��G'~��ɒ�G�;i�(��O���"���y<P��Tc���1}�^�7�>=|�:��#["I�XTS�� s6�#%c��NL�_E�UI{0�Z��W!�% � ��G��b�Qq��G4�I�B'#���Xκ#2`�&��dž��ǵ���ݞxS��~.�qJ�ڥH��`�i}v�����8�-�.j8��^����fp$�:� yän�>����i�垟�����������L8��M{�X<�c���E;A���`�|�ZQÜ�2q�ǃ]kX+GtO��6��r�����|��ֲ���Q9\��ܵ��l,m�K�P���������������j�Ӈ!<y���{�\�%��x��4��d�k���$$�vYg�Գp$��[Ƭ�$�ӝ� k�)nAu�A�Ѭ]�[y�8Q�X�qx��4y�{Ɵ�Q��G����s��ē!�HBJN�(Q#�s�����}�Ǚ������f�^�vM�ե���|Y��H�<G��H �,~]�������m�ÏH�|Z<Pۥl��#,�e*�����S�$�Iǜ�w�� �(��BM�4�|����:@����ϣ��_]U��÷��O�iR9v���[�N��y�&L��,|��a���.v�w��8����x��`#�a�/S��>����y���WC���g7���c��n��w�=`��ڒNݯ��>���;���F!�c˕�9�?K�g�$��~���G�f��o����:T�W�#���TO��T�,�$x�;��:�d����+�0�#%Q�{Ll/��1V�������6�C'��?�-Ff\�ږ7a+,��DpaS�zTcZ�F�A��H��MJ*Q&��#,cqa ��(8�#2*"�OSi6���8kMjD��� ������-����Aȱ�a�ILA�"hhn�)"�4�[VW�c��'�#,Ss��d�!�IUP����|ѱ���J����h�i�'�~��oG|��,�1����wH�V��xMf@z�k�ahf�䮢�ש�N�,;#,�.E�L��%.��|7����?�?U��G#%����QMF2DH��@��b��i7�1�lXT�Q&F�CV��6ƛf�J�Tꪀ�-m���f��q�����噧?�4_�'���I��F���i|8Z4Ϭ�f�c9��n���g�}�o���f���W^�����%��[?7�����1�za�ϯ�<qM☧w��p}���c�����p�c����4�����eVMq�eo��9��5�0���#20�}�(�H�Aá�au��y�=߫�_�W�N�_yD� �+��\#%p�j�m��8m:�|��xY�G^p��xYu������s�쯓�������k���^#2�ԷS�?Ž�wF�.��n�:��M?B&��g�iK &��� �B�(�~^������N�����Nv�&���1[��-�D��P�9+��V#2�a"X�#2%� �wL�Ŧ�F �6En���^�z�z��U��*zr(�5�� F)X�`2(�-p��#,����g�F�#��UZ��ڌ���Z�ʅ�`�$��M��x3��v�%r(*`�2�shف�X�;]g6��%4#,�c�!��bY�0̳�Qi�#N㣩e-�g��8o�)(�ւ#%�#24�����ˍ�aWZ�w��i���D��D�P�S������Q!4�?���Z�ī�NB(�EsEQU֙Q�u�JF1����t~ V� �|��AI$�9�%!����y- �E�d�c=.�ý]Q��Fh2�_�;�:�9������x��_�;�h��QON�ׯ��D����v�� �S���(}�f����j���q�h��4;����f���#2�&t��2�|�MO��ݹ���ه�Ǭ/}����6DDN�E랺qo^Z�3����pYe��&�~?��s|��P�������0�a�H.FW�)�A~����^�SR8�y���P��6 Ҿ�Ap:\#2�$�eUV��G�Gp���č�'��x�����8��?������|���a��=s�>ښ���g�����1<�Ta@�:�q�;��π��}k���5�ۨ,�fɝ��%��C����΅�����f�#,�\��S]�y$�$%��ק^���ab���;�>B#`���?��<KD��p�Y��ʨ��U��VR62B8��+�K����O�e�y��yte�(�7b��U������������O�~_��i[�Ϸ�凃�ֲ`�(!$�%`�g�\�z�2"�c�E��Eh� ��i�KC�����ۦ�R6�k��OZ�,[�W2�a�jVi�V��EXf�aF�y#�=�fhPi12��X_4MZ^%����L�{���#�[h�>٩����X,�m����#,߰��h�5`�yT�eLzDm,ݹ��#2��$d]_#%˒�tG5h|j��oV�a#,j��nD�MN���T#2J lXdL1a�4Kl�#,��Gr�3�t��p��I���X6�jn��eɶ�*�<���Փ&C�;���^h�EQXaű�����x�d�4�Q'�A�j��)��o����6L(:qQY!.h��z��R�#%�(APE�wn���p����w��S�HG�ߣ��$�#2Ze2C����8�0[Ʉ��P��J����鏰����2�q�Bݎt�z8mG�6��z�>��*��W-~�:S���0�p�m��k<�����bŅ�UO�J� `ӌ�w�r+�DjGH�����Ҍi�O�|t�Ud�N�G�#"D���f�65[�D�-���J�t�;������p�ﴱG��zt(qPGc�E{�/F�4��R�h�D�*t6���c����6��U��D*r�����vk���5���$<�BPXY�[`�!���5o����_]�}~a��ys@xy���'^�vZ�C$��/_��{����y�/PdVn�l��ɠ�rҴ�uF:;H3�+�`� ���PJ()��!��8���s�#.��@��im���);B�.�����R7x266~clyUE#Pm�]�B�9"X�<(��Мk]7��f`q�M���%�Z8&eXP��XJe@���0߅+#%hf��FR��PC��!�YJ(K�Lė6J�3�%���FHp,7q����ςj �]d�#tt�p�Ѡ+4�غՍ&3�6uvh.>����h�4�#2ƙԡ�3$c#k���&E���v�`j0t�E&Y#FS%|�Vn�~����^��+�O��E���6�0���[���j;�:���'>*S�V4�^�:r=d���C`M�\}�v�|�E�d+� w��-x@�UTwC�$'w�5�HK��ƛo�m��h�b�9r�S��^@/$T�Dj�m�Y.��#ԋ��#,Kq��ΟS6���]�y�}�f�nM�*�Kq�{��Z$�-�<��;�HUP��s=��m�(#,���f�{xm�E��M��b����4ӓI�D)��0�8�R()�#2����5Fv�(_�B�/�c��b�XR#,���n���|J#/���j�˅ �֥��C���7�p(�����F�D�d"3]�(أ��#�pk�}��-���ێ6��@·d���1�����gm�p�5������y�Q�boyN�>�t�A�m�&�#,�X�)��n�TR�O,YL����F:Ƶ���-#%��]ڗP���*�:��*��yZ���eTp��JJG���ʻN��s���pq2[�[`��;���F��2�iJ-��8�M�k]+���(5���#2#�ࣣ#`إ�q��ӽ��mGQ�gud�bY+£s���o-��o�ȥ�#2�O��X��#,����.:1�]"�c�"tb����3�93�eL����k1�f�t��f,�1�+���&5�Sa���rI�6A(�%��h��v���:�0lr���NZA<�kRhdA�����2�=�+^]�~����!'}��J�,yv� c�Z��9��z����2ƃ�7�����9S!mD���;����[i��\Q���=��'�#*�}y�յᯡ����q9��"���'�aMm�M?"���w����]x�ޡn�,��������<�XM|an���!ԥ���Al��K�;Ɩ����)�F��P6��,��-�e�4��e.�ᵗ�����~n�k{`Z�V���(��~������2e� �$#,{F�(qCv)5��P��UD/��aX���O�I#���3�+�/��u]k]V�ӰB|'�6��r����l�����"��Ҥ��|â-I��Y��D��\�`%dn�;l��B�#,gPc�B._}�Ҥ�z)�$��i�^���)f�]y1��W#4�*�����-���ѡ��ꢧ���tm��Q���S3u#,:y�,�ۀ-��8Q��ug2`��#,1�(zoZU�ެM#E�����wey��y����1v�ۂ�O'�g�yBt�ټ�2Ҝ!5%M����`��3�ʄ��1GQ���!�N���+����0��$�����-F��t����1����n��Y�zY�B5����98�(vA��3ij/��Q���7v�i�'�8u��.���þ��}ƞ�!4�#2*��d2M@*�_�K\p_{�ԍ�,W�,y���?B>z��`�x���$@���a@�������Y�3����E�r�ظ��>���\��>]���2�倹�iߩ�S�Kē,M�@����@H�QH�ڢ� �A�K�M�!u���mg�����m�����)�>!e(D*e�l���`�#%'���߁��5l����dw��A�<7�F#HX(�#%���ysd;�qQ����Vw�ДpUBLAsv����K�Ez�?��+!ܠX�t��/dDF@��;O-�d�1�N9Kɏ�֪��xήQv����hJ?W">Y"�d�p{�#2���l��8�{`�B�����tf�o���ؔ�*�.���� [��5��., MK�x���ɘ�|�7_<��o�l�RU�%�eː�L�?���`��1l<��EjX+���kN<���q�LJ�Ϯ�I�b%���0�&��1C���I�5Vʵ��9���:`�#��l�L:ߕ�m6�®�j'ɺn#%��}'���][gɐ�b�Q�,�tv��L莓¥��h�,�LT&����ɀ��k0�7+��4̪�ȣ��C���{��%}}a{��M��A� <� �MM�-e�q�I��G����טVb��M�䆇'd(uNl/�B�d �f�M��י���f�Mt����m�F�P����i�1}�CMM<�Ԥk>u��1���a��x��zS�N榈����W�����Mvڟ��;╏#27�4�1��~<�c5�q��^���n��M2s�=��]�'?����f�(~ ]Nc�B9�~Q86���72{��[�u���Y4����bG6�H��c�fseXuaz�>x�L:- @~�གྷ̈�?_צ���"�!4�~ks6��#*g-���M�/\Fd-��F`��q#22����BƂ>?#<i"A#,��/q/C��_�� k�ڛC���;���OWw�Zz�`y�.n�ڡ-���'�W�b_�v1��'��u�v�ˣC�7ٓ�4��O��e���#,6��7�x�3LuGY��>S��!����jan��f���08�"�@�@��R>\}[���������c�r��XZ.�,�����#Ώfi?#��G��D��������=`��@�����#2�o�ㇿg�enk�kP4�����4�g>^����:��v�$N�ׄ�J:����C1���a�qPLEs���\�5���C���dψ��AZʊ�.0[��nq���F�a���χ��Q���j:9�9l#�H%�n+���ȩ�A�f�~���{NT�0 ����V�&��g|�͋@�)է)O��b�H��g���}�b^j~8y$*�W��V��7ڲ�����ф���r��g��s5;�Guµ9#�����S���#ܩ�1�ȱf\l���.u���_J�k��8w�a&�J/O�K3b^oB��:^��Y'��� m"��;ڵ3���s��Ǚ#,[����oυU"ۑ��̝[~�ڋ�&�*�M.�`�V����*��$�'3���gDPрe��˽(C��;o۩�6�����Њ#,�"#2*�V��#�����R3�����6��|)�8����7տQ���e��#$��XJljU���c:=\ֻ��KtϜ�7��jmcԮȶ��d#,wgk]����z(Վ����\V��Ӹ���L6�$�E)}�'��}'n�cg6|$ P��M�SAͽ���B�w!b�^�����(|��ѤS��b������*y9N��_�ǑFo%�*��a�g������_=�Ro�V��έ� P�[�+�8Q��h����|�8���_�gcc����X�*�Q�o�H�G�d�P3�4�3#2.IDg_�#2��ۏ~!�ʨ��s=T�h�q?�˥�� ~�m��i����l���J�{��̘d�싽��e��%����^�QF%�i�!0�P�8�ލ}�s^G a�Z{x]#e���-�,T�e���-�6H�~��m��2&�O��xr6��['�3��껶��c}H|�%�x;�N+wD�!#J�AcFQ bSS�p?DC&7(e�㎛�VܰdQ�<�����)�C�����<!]:C���X,�d�K��듧ZE��t�Z�#At�F:�eӇ͚�H6Ҷ|���ļkg�X3s�S�������tc�����#�{�|O�;�r���!&�tv|�j{#%�`����WԒ�"q��5X�-������$[�ѝ ��a���"G��Q�f��v:��`u�#'<u��*=�$�5�UgO�t��V�-��c��iH�kt����zZ�'W�]�p�z�ƚnD�c�F������sT�f��W#2�/�9=jѴS�e���I���k��@���b뛣��X��Lm�'�z:;`��t)�E<PX�]R�רe��|����(��7��9��Vܕ;b�_k���3�VMq�����u�<�v��Ůխ^�^Q�_���^WƫW��GEVf��!�y0����>6s��L.��bi#,�Ud��Ϗj1�Y���X�>Ǽ9�F��"��+���}o�ϒ^��o|*���ZY$'�����Hd �����].\�L��7���/q�X4Vت�چ-.� ���ًE�R�t�}��yeQ��[C�����^`~�`J�RS*;-SʤR9�J����宜�#���FNvש��VC)�� (B#%�pڶ_����.���_M~a$���m,E��[��ˉ�d�M<���Rڸ6�u��ZV�iT�#23X����W(�]��Ju����(+Cϋ;�����k0�+'bS<���w2n�<vSK��9#{���f�Y�t�?X����T�Q�j?���o]yѵ夶��g�iQ����z^}�̹�m��c���4�"R��Nmݕ/�I�nd'��/aC+fP�R�ǃi/eۥ���=�����'���w��{�������3ж�aQ��n���g��'��t569��S7ήxz�^,9��`k�[��#,�[r�At�j�<�������es;�R��T2)����L�h������#2G]Ɏ6�Q��k����4��C=bM��o��������d��Gf�[�w�z���u���/�2�7L�;���?�+jZ�ȳ������髰�Ⱥ]\T:�Zm�>}J,+��o���H�nC�,{Ϋ�Me�q��ot��g�A��9�q�{}�*�ݧ�˦x�c��ei.�J�р�TX�V3yM�#2F7>˞�a{�m�{(�Q�9ڲ��7K*_j��:/a P���P�N�_#������6�m�O��5�����z�z�ƨ�cU��]t�H�K�W/���V-��!y�����Q{�,��i�.x�<\ �Ҡ@�&�j�QI��;21�1��*��|wΈ��u��d��W)�'@������ݝq�J�I��r�L�`�a������?˷�Y�9��[�#2����0;ͷ �N݄lR�j��NYX0+ZV6A-�IW{�V���G�)څ"$u�Ɖ++��'�d�-d�-�-~�axƫa�z�6D7�m.\T�PH����LĒ�U�C�nV�h��{Y*ݮ�9j�9L,��,#���7�Z1V~<k��\o�LdZ�ZC�_8ي���Jn]�Qd������0�����1�X����17��P���B�s�#,.��a�ͿX������5�L�=�ǘ��b#,.��~˟d/3���w�P�R���`�965��Zk��š���B�q6BL�X�u���zg������?1M���+��g�#,��#E�-��_+g�.�;� ���I��ó�J��Y�'_�$՜�;^ޜzX���Pw١�˷��,?�P����ӯt�q�8=�����_�?5b�1�z���L�Y����)��Vy�-U�~��v�C#2��%PoYZ�Q�NN�������,�U�(Q@�o�������)�{%�[(�^��]c-M�zB�"H!��^6CU^`��H5�1���d@�:#,?$t�Y<^��.ݞ뮭�P/Xs�s?�!�N#,��i���9/���1㉬M�7���^�V�V�@V���79Ν[�Fp#2��N�dGN����i{ƥ8S�Lz���m�X�q�����3��bW�w!��yi��J#1�L�a�W选��V}H�AӜGq�Y��t&��5�;��8�.�7M�2�WU/p&��\b27�_9_���B��D�o� ��z��6W�oe�V��(�K���JUo뢋B��χ��8#,Tp��q v�������u��`55Bv@ipx�#2�y�k�����{���2BB�I���I��=�M�[��S��ꯦM�a#�M������偎�����c*/W��j�;gRԔFͱs})�Y�����m�1#즫Y�X�|���)�c�#2LxN�%�W�B����=�Y�T��[��13yFG{S�6:e#%�}�+ˀ�|2�oi�KJ��1ӓ�i\7�l��Q��8������Ua�H�A�ɰ����)������$��h>r4MG*�����t��@r����\�����-���і��9�|�(l�X��G:\C�j��ͿX��Ϟ�f�ơI�sWD�/�#,��{����4�JPntœUM��t8,�lױ�Ѱ����*k9DD�#2T2����q�в�#2����k1~6�#,6 ����qt}����[D4j4�%�����u�fv*P��VDuj�%�}��ㄖ�\{��)�x��,�p�1�8AY�{A��Bx�h�<���{�n���N.�X�.�5��4t��6�պ�h���]7�w>(���!*��{�b��婹j��yF��u�, �Skĝ��.�wNT��5�������úRs̗�W���uZЊɰ_nQ��A�;\�V�v��g�Z�`��r{x���G�#2W��F"�\�Y�w;(]����!T����{c�&[�oH��ڏoj�{s��X5��r����H<BssZa啸{�%�m��3¶[��Ņ�D�`�֪A���ov��0�����H�p��)t���(w��Q���I�*^<���Q�0P�UA#2ѣc�wv��8%x.L���n����FD�oV��W!t�,�t��eJ����aA�~�l�͏�K,3����'�����dv�F�Yf���<x�>������R?�*��@^2].\�}����%c�S\i�������e�#%�w.�mM�B���6�֢s�ҽKRBa�֚���Rb�B���7vB�'�샚;s]���cG�����8M�7K�I}4i�C�H����t��N�X#2S�z�3fY�R�$&_}��|ȜwÔa�K�%tX��g ��%��\U�{�jj���j�^72O]���;�ci!"`}��\��x�0�팺)��rRF��U�,q�o"�\N�S��l��3F�۔o0B1C���OTy�Q��t�w���m.�O�w7��ڎh*�f������As����}5��M���ۡ�֣�+�Ω��`�-�|n�I�Ŷ�@[���2�����P��T����<��{�R��G2{E,�vN�E�Ϛj��P/%]&��nݮ�P�;��[��/�ոF��q�5��Z:ad*�u���ۿE�<3��6$���t�cQ\\<j�\�.����x#,��͊����EOW�A�'Sh;!O���q%��\���Y�4_�ܮ�ޤ� w�H#2*�-��B�7O~�"Bdp����#,�^�)��4m�Κ�K�v������z~��r����>Hا��[�%6iʟ��~�.se���3�0�{#%�>Vt$�mh�/ɛT"y�����r`��C���`�k����;@�0A�G���1�mъc���C6yv��=��S��@� �v���#2?��r)Ń�{��#,�"��dn#2���s��I�3����aӃ�������,�{`���A�#2/, (�%�+z�u�[��:mP��G~楲%�sB4$��'�Ū:�G]��8q}.��B0�E�h0��g0%�[9HW����;��;��t�i����pV2pv�|]x-���Oge�bG���6J7�r�*�J����1�9]<�%����);/����Q�5���5��Փj��C�(�=��2�6$vY���%�*� Ě�i=߆���������a�=������H\�i��8XL�QP���/�sۤ�z�kӾ!�5��Ҝ��gq�#%{���z�.�[v ���l���0��#,U�b�u� � �o�F%̊ZZ�4{�.�:7w�x �A��vǔ��#%��#2��ONʆ�KE�m�߳����H��C���� �v�N�S�nA��R�����y�ڼ��7�Hg��EZ�'�v�l�*�vح�I���O$_*:*a�:��ե���� j˰[��C�}�咊�����G�^$�����Y�sC��#%sL���u�G'6���$��<����|����!������@�_�`�u���4�7��$�����cc���!n�XbQ�f���@�#2�鰄0Y�=-�|�^f8F��{����</��}~��w��y�� �JZW�˘��#%��֠؟��Z+��`�5�9��P��V�v����4������b�Y��g�xTWƮ��]����o��ʇ�"�T�(�~�_�FĤZ�l��Ԃ�{4'"%�!D�J�e�~��0(#2��qx��"|���x0�"Л���b�b�j�mm_�_u�،.�M��9&�'���3)ڳ�g.�G�O6dj�`�<�W.�����Qa�>�F����(��{�ﰑ��<?$C�9�vZ(�mWr����*�*��F�P�-��&��Qg��E(69[�D#23h[�$�(�]>Nt�"rNK(����z��K�d�n*�Ŗ@��G�E�uo�^�������0nCq��.��̟����B�=w�c�H�5# 6����6.��3��\�#%�|�#|��#2B�[�4��#2��"z#,:q�,�!�c&d�?W�T�=���H�.�Dh���G�O�0��0"#%�>����KN���@ *�2�(�F����K����ī�ตhA�lK�:�r^����쳏�t\e����gr�Tg��d��e��:�!匔,�������&���oa�\�ߟrv �@@�P��E3�Ӻ��?4�C��R���7C������ C�֤�BJ@���#%�+7ag81�ʼn���Xt�I��Hn]I0!�aT67a0�G��#%�h�����M1��{b��2!�do����d�t�a?��� �}��͝�}c<h�>���n~�V:��B����C������v��|3K{�C>h����&A�Ľ�+"��]��ez9l��B~�9�:8B_�驕����]�{UP ���e��`�ڻ�i/H�7#,l.Oj��:���AgE��ܰ���߳�J�'���ܟ`/��g�wG=�P#q�Z@�5� ?ҝ�b����<A~�H'��ݏ���jҊ���e�ϯ�����}tM�1���FQǧ�����̪��Z�C�I�)@�jVTԿF�s�f�4E�{QO5p���̑�dd$�UL�c#2H�{�'� ��i��8cm�S(k3�8{��HV#,��|N�6E��I�0�t:�Q�3J'K�g(H%�E7�GtD�8����Iא��^G��@PL!ػ�s��)�#2�vE��neQ�Ey2! ����݆W<�1��J�`Qf�YA�7M��u0*"%l+a僿#%(1A&�Ç]�;�h��rr^�{��$#2g���t����P�O#2B��T*���7L�C�7��#�5��h�'ˑ��ؔe3�{��~�C�"a!�$����z��ޱ�=H���8�3h�+�#,�� l "��Z����i�'W�1e0û���@�"���ӊWW@U=E����WbB3(��e�6�&��u�F�� P��c��������ɉ<��٣���렃�L`�<�8���OguK�A�#?��� �%������-ۤ&��������^�<a��-@&�9���SnepN�W�/Y�����yA�ٜ�w"��0�mzg]%�$%s6J�H�@�^V.�Dwg��R<�,I�a�����uZ������O��-q�~aN���~��r��W�iJ`89z�Q�@���-�&w�oĪ���k7��b��P��I"(�cb�r-��h|�#%GcNN��3Oh4����*H-���t,�?o�ns��^��8�R&C�1�37O�Yj����绣D���-8}r!e��g:`�d��uՙ�`�QP+&ؗ��`KH��6��C�Aݝ���Q"�<�/pp~�{ܻa�;p�x���I���k��jXى�t%�k�����ߖ�!���_��u�d�� vL1���,F<JҐQ5<Ƴ��%~�� \:m��z?MQ����a�Kˑ����y�߃��OK�u�.-���?Eo3� �$��#,���h�B3g�#,��?(Pq#29d�7�ĵB*@!�&`(ouG��#9�$�9�>U�m�(��3-��/+� Qh�s�rP#�sݘ\�%���q{;��z|��*��E8�i��qIIh� B+���<�C�)^�`��a�qߋ��FR���8BB#2�\E&e.�����ZO4�qp��[@(FB�x3�\@H��y�.����ޣ`;kj�ι?;��ƥX���[so��{�I#,&���������u��/f��2<��#%�m���?��*$~��Ҵ�Q3�GCy�����۬:ї��QќHw*������`�&�x������{ZR�|#2=�q�<��*��p���z�&���H#�s[9����Ԕ�dē�Xo�R���m�����]FS��6)8xL��7/>s��aѱ��G�O��T5������?.���\��3c�{ ���[�[G�/y�bB�T�o>��d��t�E���|6��^�\I@d��Q6GX��F�t����"�͜8E֎v���cΓ�^�z�"S9��s�ྪ��YR�҃[�&Mn�*I�mRt�-����#[��4Օv[7��'�~��K�O�����ͪ2kM@���y��5[z���yn_o��@[Z��!�&(GbL##%�m1���҂V�_F��m�?��2_P|ƝT�9�3�j�I�Ȁ#� ˼���s"c5�x��{?(l{��ݥ�7�:{s3��������v�ۤȜh�RqG=�#21��RP�*lҋI���;���W�:c ��k�;����,p�k����7��=k��z{�.�m�#,��ro̟���-���|S�ϙ���ċ:21�N���MT�ћ�U�%=h��Ĕ�y���k��-�������u�"�JV�ݿ:v�^y�y��5���?��/��ڦ�����Yu��*��2����Q�B����χ�i�:�PUT��#%����'W��)Ù�<<R�?�������0��z[��}�x�2��kod�(#%�>�7���$�y����'��/���A���B�AW��崤z@���g5ʮr��8�gv�M��?3#2!���!x/��^��嶹�Ջ�պY�p�:1����u��؟:��/>>�b�5NP���G�˯��f�__KW@���*����J�!�q��TSl�c�f�V��yW�>4��U��5��"�����K�����e�=�ֽ��z�=`��������ݿ�Yh6�G��:�#2*_L�I�����Nb�����ꊂ��"i(GW��_r���Y�Eu�I$���Z������8?���ݏ����TJ/�fr�?k���_����<#�=,d�W����A�����}�C��'`Yr�a�ցl�t2Tj J�;T�t�Y��������[b�,��"�Z\,7@��.!f#%�[e,쏦#2�2�)����$��r��F�Ad�Ps(h�ʂf:�X_���6ƪP#dԔi�]��c2����,�a�D����)K5@(ȃA����-A��!B�=��?%_�T��n��C�R�x��� E�U., `FzU��������1@���A�W� ��3P��ܬ�.9X��2!�������vW����s��l"w����6f)k�}���E�և��X�gQ�HJ�QO��=����\�9�gMoӆr#%I�1�4�^�n�ϡ#�������~�R&�(��`<�$dāL�Eͺ��J1�V��7����>��ɪAI-2�'-�GZ��]��5�}z���:�*��p���️�u��=д�+�Y�G�&͊���F!�S�:8i�5;<�@�FI4�?Q�$7@�f������ǝS��Q��@y7g�z�6�/U]�^`����N�ޮ�l�>q�!��h��Z�B�s?D(��J���A�`!P��hP.� �d�#%�Onvx��;���4T,�Yd�iR�i� �"���zι9*����*���5�'��<���!������#%��lCV�,��f�u�!{�*"bcaԐ�HE�{K"��Y2��<p۷}EOY�vh5&�c$!Q8�(��)�:5�����P [�rH1T�ä�;h�ld�hf�ݵYpp�\Dq#%���l(h=d#2%�Z$�ْR�ʹ� �HQ����M�6`hL��w=>s�~,���x;5�So +!� 9�՝q#[��`i���#�D�<d!'�<��{��D,;�Y�su��%��n���+#'�Zu�b�x�Iܞ��Y�{;YQ#%�,j�����Zƭ�u�d��V�m\�&�r���z�%�^M�c���**�0X�^����ef��ț�r�������m%#,�OJj^�4�x�t}د~����r�ԵR͎�<M�;:��D��Ϲ7���q��#2:5��P��ñ�Z�T�x�t3�|�nH����ZM�h����Hb:�d�:�cV#2�r�ï ���u6���r�U�ȥX��ɣ@ǪK��T���$�2�x�IIk�P���(S���Z��O��-��<Jfٛ+�\0nxE��:�ZpA�74(�(cm�����k{����ر��{˥]�[�Z���S��Y�w��q��}�vo.�x�HL��w|m����6��!Ւ�<��2�� �2�x�8箇]���1��g4c<�e�7d6�$2��o˗T�_5���=V�7��$�9���Ř�%�yRZQ#j�RKD� c����rԡ�t��u:��cH���)c#%4{8ƒ�G�F��ƛ����H�i� ,�Ј��꣥Y�&�j��ȡ6�A�o.9�;fF[�u�ܱX�a�Rs�'o�:�H�zq�F���Ϛ��������G����Ǒ<}�(�$(*�F1`ԁR\���=yy��U�ҒX��nc/]������e0.�UR�U�Ј�X��`�υ��K?=U�����}O�l^�Wh�FAP�P3�hO'ԩ�WҤ�$C6E�3�87Xd]�#2��m�2c usc��;��_r'����#����f��,� �;�Ηm0T&�S+���a8G�?64�1r��/xw՛#,y�f���#�_jL�2r"n�2TS��a0�F�/.�d�`J%�6�E@�fT���<���j��#%�3�:h�5Q����VbX�D����ӭB��#,.�r��0�}"�6\q�6���n���$[`P�M��xσ��Fm`r� P!9�P�L>��;��^�Y5ˤ��㑒6N��Ԯ�4H���, yT)A�s���۸��ל�2��0�n��cy��o4v�;;��t�9�_l�����O�Nj�e<j�Q`x�dom�QU����;�Hs��H�����P�a�e�ɘ�P"�^ӊO#23�/s\�3��'j�o w�>Y�vJC�Jc��j���d�RAɿj��֘�'�=2gBkV.(�;����Kc�Ldq=F8�G((0UE��dQe#2��:�k�.?�i�k������U����m�{����fm4��s��h/l��{�,y��s�����Z桧��oc�0rt3�,4� �&ۘ:cU:��ٛ�B��(���!y�m�t����6��O���ﵟu��7�&�`�Fkz�f���X�%��_�0��N�:���:!Hi�������M���*�Z�h~ݔ1!�$H�e�:��n������s�����5c�_����<4���d�nU������HP�1���!�|6<Li�(S�K<>B���+9������·�����C�S@��J wE�צ�-QX��"��#,-Ȗ��uوb�ȁu��)`~㶙%���T9�l�����#2�ƀn�x!�=t��+�4�q�#,vg��~W�_#,��x�)ĝۉ'�-��s+���p��ϱ���#2�_#%��q5��)S��L�6�������hQ�r��(�B!�]�7N�$in��OE��k�'Z.a���êB�v�䫨֖���j�eE��n�&�&Scy����6����{�]�6@��4w�3t����%lG��e��$�9��mv x�a;����*Ƚ����m�f����|���<�xT'U+924�C��N��� �@��=�_��Ⱥ�Qz�w�"���@�#2x�þ���~�j��yRę��c��t�v#%6#~�,��2bJ��pZR����l� ��>��?/v|JO٩i����=����L=h#2�AQ;%��∔��#%���#%?/�6��`��Q�g�`���JР��Q4Z�+q�������4̨�;�߯���#%L�#%M�e���.<h��y#%'f1�)Ϋ2j���� �T�������N���$�?����p�|�ݢ{:�_�e%A7�~8�-����߷��1gQ7�2P��q�[`]a�o>��D�%�e�� V�� E_����?k#2AQ�#2CD\���#2�O��]���#,���N^;��mYmΉa��c?��#2C~� I:���u�^�Ǜ����4��3!������I���;z�^xm�Ve�*�����/�������������o��R��M��ұ��YAτTW��ߥ��,(�+��py�ZG~�C�xDB����#%)�vyg�w�Z��izQ�y����}�37G�h����W7�D��}_`H��%Q#2�7���>�='�0G8��ۍ�����i�ޒQ*���@qg��w����q�l�S�e��tׁ��^,Q�/�(2#"�����؍����x߁�����{�3p����RJ��A�>�{@%ʍ@{�Mtܞ�Ѿ��'�25���Yg���~�g���/uD�|B_pt�mWAu��]#�v#,B�54Ҩ1*:��D����ܗ����M�#%����=z7���#2DIg���]����}z�|��#%K�R��dݛ��|I7f����a��{xb��)����mz|�F�&y]<"z$4�,(���;��О���j��:�>�o�g��Ou��R����ǎ�}�6ƀ�`BF S"P�/�l����~�^}~��LLN�윿mwc�:�We��i"�G�tO{�j2i�9������gF�D8��&إ��BE�&�?��ϳ��ƪ�[�Í��N`Pbtj�²�NN�ӳ�]�#,�y�[��D�旄a�4f8�zϧ�X7@j�tg�~�������o����İ�$���+�/�cⵐ����Y�d!#2*�=��x�0�#%��V6�b|Tf#2W�fg��m��Jz��������<�@�^�D+�wh_%}��.�~R}>��!$!g]��������.�?9�3��#���R�#%�zCʹ��3���<�O�AM�\�����GV�(���y�(@���,�{���}�w�~��������=��|nh�g4�V�� �=��3>�q�]�l��2��:'���Y+�i��O����[���D������RH��Q�\��#%�D���#% |5�X���6<D3�^�8����S4T�Oі�x��D@#`~�\�:�#��A���u(�hZ��Q��|=;wi���6'��@�خ������3�D}��)l~o���-%JUA�~5\h�P&���R�l�#,�������1�}���n�� ڟ$�m��QR�<��#2�{�Y�(�H�$�+"�O ��H���� #2Y�tc�^��<q����wc�y�o~u���� �p8��m[����sF�����gem[a�#2���3�f��S��u�>E�NB���&jB�p������aW��ey�c��"4�k�Ϗ�Vr�/��wc�#% �a�%<j�=���ש�$���Ϸ�Ny��#,z��>����U�P�Tav8���d3�ͪ�^[64^�S�s�R��Ԏ���y�\����W��k�6�?�x�M�v�0�¨r"�j�zz��C��+�~?��#%�����+]�\4z�F���� X�怞�s_ӻ�_��n�D2���z>����l�/Fz�Y�k�#,��B p���?�9�&��`���^#2#%��|J'��o��<���.O��t9I�C�@>%sϪ�Z>7��RE[k�g��9�nL�W�]��03��{!�뵋���X��5��(Ȩ��f5�tB�Ba�I�Ւ:�s�K=����^}L�r�W��<���*�_����A�FL��>`�j)Fy\���w�oq���1�Qq;��5U^)�\�ec7�)3��S+�Ph�u��c��j!%����)$y����O����+�ڳ����`̢�KCH�!ѥ�ZkV<�ֽ���z��l�hu��A��_%Sw6�����q&S"*ޙ;�c��oƍ��]*����o}���e;x�@<���G���#,��E�|9�{�Y>�q5�!r� �܂^�������m7kh�U�[����D�M69�`�Q�k"�zJ�%̠IR�Ty`����,y�FP�L*3(#,��tG�(�+�}����z;�A^[��0M�ǿ�*waF��7�#%��h�}lɤ����Z�89�=�>$f���/���/ǹ�.��M����*�I��^=vr������,��MY|�W�D���ߵ�`횘:2����)pe7idv�ʽ�F�U�Zn�W�V�5�`#,_+��]� &��$�6ƽS�r��M�:\Y�Hs��dxX-f�|ҎQ�w�vB��ϖ�Pg3�w[̂®�ޝ�w�gFc�'��3�zgm����z�1;�!���_��K�H��Mq��:��1��Ҳ���)���R��q�v��j�Ƶ��ņ�v����[40��8J�d�V��N������Du����h�O���o����l�y���!̷����0�M�Ӏ��u�@_v��Ԫ�X�#,�ٟ��G��>E��;��<+��ڞ��TSj�Ԥ��t���ƭ�S�9Q>���ῴ�����Ûӯ�4qON��4�)�D�_��E���<�5�N��7���}uKfs=}�؊z�_C��|h�mseT��J�?d?&���֖u]g��c��Q7n�62jLK�g䉎�˱����u�Cm��zË�8���>S���N��Bt(��N碌΄�e�.�h�EN���t[��Е�=���g6����v����t��x�N͇$�����������9��xIE���J"���L���C�k�LrPG;AC�?��>/9���)k��� ����#2�;9�EMIڱz��+�~��d0z����O��ɢ�;)p����|����&��=Q�ح�9�3f��c,��4S�64k�/��:��"���:t����Ã�t�G���X�M�/�]�S��J|�;�%�m��˯�#2Ϗ�97$�/��)��vs�z��<�vÉ[�xb1�(���n���>�f��"-?k$�Wj�!֍�܍|��ML���)�x��zg嶾t�~;pD��;��+�o���*#2��drm~v�n?��&�5�J�~�?X���vxd�~ԹbQ�k�i�p��VW����˟Cl,��!�hP��|��Ǧd0w�i��w�s!�<G��b�ܯ��a�N8�5�@���2eH㡙h�' ��Kw�ݏ��.�t�ȋ��}�|.�����5�����ۏQzm�z1G�?ښ�A#�Dy��-�}f}����B�i�HB8����Ж_�W�.Y�5n�{n��|}��\B��!��[:Q�80���˰�OVdN��n�0�}L��5c2|u�m>ѐ�ޱ�����*5Ի�5hd��!^ ��z�r�;8�m"����[�˦.I�<;h�#2�Q.AQ�����xoZ�MS�QB0���Fpqu&÷��m�gۚ1�9���ߞ�m�H�?@��EӼ�?>��w�Q:)�$�/Ky�i6�+u�kJ�����E�B����Ɖ��P��zŢ!���m�����iK��e�Ax�"�d`��($�R}#2yw:De�q Dl�MʨZ D]�*�D�CE���c���cҞVO���z�����cp��UʏU�@��,ZV#�%�(��='��g/l?>ϝ���E8ꦡ���Ѷ��8�n��P�4�=��<�x9MI�B�QI�lV)i6�u��c��^�~�|�����vu_Y�>LԞh� ox�}�\٭B�1�1.6� �0 .��hlS"���cR(�?�1Go#2����@LC�Qx�#%r�@��M�v��6|Ni�!O_�P5}��X8>Q�#2���dguAX�|���\iW�����/�fx��Y��p�f(U�:�y���C���4^�5�EE�E�#%�Ltg���z��Y�\?�;_��"�{^�#%qP�:�c��=F�E���X6~��Ha�dk�q@Ow'q���j� �����s���pȤX�)?i#%��H}�<����7Ԣ����$���/kE��~ڴ��=w3?��E�x����uW�`��]'�$(o��i�G��4�/��+�x��ڱ?�/�p����M ��1R05+�)��;u%�o= '�Ο��M]�C��Z�q��K^�#�p�=Cgb���������v�A�H��GGH`�ӤxE�:�W>pZg(����SW�H�*Q/�G�oʃ�u����DƮaj�b(�U ��!��i�D��+h���@���㟟oOEܨ-c�?����/����#%��N}��� 4��E�8,��\K#2S���������z���7 �Zu۬xd�J{�$FC�S���ċh�;��l�uq�[g�g��i�v� ����ρp�tA��V�#�t���?8N5\���7�M{�σv/3��8�5A��\줝��^�-zc�������̨��C���(H��HMPef1��A��{�W��\���@X��\�%AC�_���5���F���Q�<0��,�̠�/R�(1�,A�ָ_!}���'�|�1nCs2#2�#%�EM�r I#1;�5M9�ˢ��&k)��Eџ;���!�]�?�9#%[ ���Ě��P)M�1�@��D�������9]V������_ ��4���<��XG��暉+����{���Ke(ֽ#2���0�Q,O��I�=���`����n��?N,��>�9��P��p�M3l����Rw>L�)�p�8���`wc����H}yA@�ǎ9jW$��O����*jW�����Ʌm��y��C����(�*N���#�h���4����yޥ�I��#%�m�h��@q��g��6#%�3T�J#��\�U#,>���I�zە�^�n;�� {$Pk���>n:�k�B�E�����9B����Y�� ���<tG��/�i� �?���H���g�֥||���G�B�J�҉�Ue��*��)(�Z�����O��^�o���1�x\��� b�Z�a�<r?��0������7ܣ�%��i8`�O���;������ۘ����W<T�0L��|�м�Wɿ�x��9m�~}[Χ����ݦ�ŕ��YƏ�"4o�m���u��6/��p�����Z�i+ �:������NC���Zck��;��.��`��BW]��z��4+�̧q��$B1�H�(Q���}X�`}R�s��l���f�j5��yv*�ܧ��� 0�gb]�<�8Sw��yD1�-#,�@f�B���)H���n�����ߺ){؆����}i��≙6��{-�KsǕw��\'�q����F�nd�n<�i���Y��1��o0i���xt��/����44! 4�ߪ#����C�f�E���}.�ȵu�`�[Yڞ�Z��`vi�A�2�<�ɨ�Z]&r���[=�}s�U���]���i��[�a\ӈ�?��z4�{0%)��������#)LR�U�fzgt��1����qZK ��_���%����I�� WD�w�:Y}�����L��uDu�h{��I���l��WX��#%�Z k�1{,3V�#���#2���`��-���L��7�yP���t@��Qר��l�\��|�=C��}�9�&K��}��DJ)6�}�p,)@%XMv���^��Y5?v�Na�|�F��a��+�F��{�d��~6�`�[�,�R�2�j�P+ik�Q���V^�s���>�����~�nZ�>i?'�k|�9��E#,8���v�'Hn�s�����֝�&���S<�xt�m̏�j�\B-�B�s���:��? cS=�S��w�N���q��Շ�zv��~�6�����X�)�#����Z��e����}�#2�tDZ#,��WCl�S�W���g =0���+�A7�)�������o�RZ�3��#%�`���]��!hi������^�E�T]r�p�#��}:z����9@�Խ͠{��@+���i(s�#Fn�4��<՟�V�*� ��)�ifK�^�w'�ͪ�RJ���*�a�!5�����`�Y��x�,KQDJ0#2�y�� �#�785�aڏ$�P�I�e�#%�-�O'W�f���ۗE��B*��o��p�_���[�5Q��A���w�y�����- 2�TQ4�U��.�$���a��� ����L�rd���']�"��tځ&��d0�JDp㭼^9e!$82�#,f����4�Y��{lA�2a��j:�;%㖣�C��Wv�7g���G�0��`�AS0�;{�UR&��nF��YK�p��8���k#,�h�����lz]�}�B��x��k$��y����`lA���d�:�p�l��#,&s\]�S��x�h�մx������3� �� 9�<��9�Œ�:1��#=R��v�w^��_��1�m3�=;�K�x�9���%d��j%A���LS#%��dTL��P/"r�=�)���zL��Gv�'�t|5����m'^֩qXfB�P�ҡ�Vfnޡ�%21m��.ȶ�6�qv�I�|�_��2G�OJ�;S��}�6�f��g��'\��t8F�i��Ac:#�d�hɪ"�5e��8��:�"��55�:��ӿ�NN���ܻW$�r����|\�a��"}�����Rvm�O�W_|C_��x�dK}V�c*�c�B����y-Ų��I�ˡ��ꊞ9��;�=o��7/Ԩ�u�4��Z^���x%�����E��Db��=�"��fW�h�efKՠm!��U,"8^�.�5����-� �p���dE��ն+�L�Ǻ��v�xu��* #,��+{X� �H���"����A=ݣ��u!���`BP��F����X�{���>�����u���V=�QE��Ns��V�-h�#,D@|�i�A������B�"��"S'Eg7��ё�m�xhh�Nf�Cc��#,h@��/��6N�j��r"V˩��|�ص�ۖް���"::�b6ů}����(���_9�\�3V��Z���辴�+A��u#,����a���oR-�uH7o�d���YVL��ٲ��mw:�h2Q���x��=�(D��+y�puK�D��!v#+�6RV�#,��'I@��m#%�9��GN�cnb�Ki�H=�b#%�n�A)��إkNv�yÅ��N`���&�8y��I(���� ��,[�t��!�߭'ܫ� �d<��֑���D��-Jw���l��"������hd�:\4�nE�э�'ɹg� ^x�$Ƹ�bR�p���ԎG�5���2�x�꺉�pQ~�pw�#�^�iP�M�h���YAlD�X�,;^���>O*/o���Ɯ�#2Ej�#,p�C ��<)Mg��p�xE�Ú�f�ب�#%<*&���A@n~~~��<8�,�[ l#2ȷ�"{�vʊ�Sǯ��ڼ.Z�Jj��|?��[�]Mt�o���K���i>�Ǣr��.` M���ճ�����=ߓ@������~���#%�(�� �'�-���>VJتi�x�I#22���}\#21�P�Dt�ݔ(�8�'��ET�#,�����Aw�5-�Z���O��V��9�f���#%|'۹yyB�#,՝�N'�e:�͟���_��\߀���y��=�e�?�o��?D-#,යY��Mf��ԉ�)Ǐ��#2$ר6l,��×�������������Ǘ� ����pl�U;#2�8�DA��!#2�⇱}��#%�3���@���� O�~�(R��,��� z�rJ��y$T�I���S���%Բ�w��W�?����xv#bQ`���(�X��+B`vj����Kyg�������v�v��������������ގc�˟b0���x��A3Caڗ �:�]۸�xn4����rk���8�*ɟ�Lc�T%x��)F#2��eف-uTy�|�;��`x��G�{�ڝ�����_H������}�q��j�G��GlV�_��RȾ!��"v �,���/r�����i���i�m�.��#%r5�5#,rN���lnf���/1փ��" ��������]M����� ~����U�����_9�Y�B���o@0 |J���q�rI�L�+������"8��(#%�YB�����p����?����r��kmd#,���P�6}|ڇ�T�` 3�����n����$ A�T�����%��y��bƵ%$��?�o!|��e�1����a�<B�#,������\�6M���h!f K���0�e#w��#%���Hm5����E8���0i�-Eb��#%ͤ16Z��'�P8nʐ��/��� ���φ�*�ܴ=����A����{���t�m� �h��M#,���%�1������;���6EA��#,�1u�D�BA��À��{�\k�iJ0!d���͐��.d'%{�#,�c���b��6�V9'T��+a(-��7���$�I�W���#������o��e�HՄ�<��!���M�H�����61L��r���p>9 O�#%@#2��]k"M~�ڎw�겿�ߚ���l�vFl}&�??���R���Fv�7aב��`o��f$=#У#����'#2�0E�#,%A�r��J"�kmb���!p���+$�~Y�yv�#��w��@{%W��SQ_���[vQǪ|��<�ɑ�:0�Y��������k��uA,���;�q�6=�&@Sj[�Dy�>��Y:�Z�� "1,�N�RQ�fK�#2�#,��d���x����"#,?�#2�[p�����4�* *�D� u�s�mos�!֦�t���e�S�E�͕�&됑��x���6�4���[y���B�}!(�<r�]**�e�9�UU5��>Ri��c�#%����:��?�{�������#,�2C!8:�Z7;�3e#,�s�gL�ؖm���,]�)��o�3���г��W��ue�G���ש����r;T��#2,���mX�տ�\����6˯���^�G�F1�}wUz�#,���I2p~�@�ߨ<� �20��>_��t�� b{��Bm#2gSS�a��،����0U���k���.�h:��Pd03�f�E}�>��J�R��11���sYe�sC��>�QË��7����lh4~��6��D�����Q���B!���!5�>��O���hl�_����A����֦�r}�sA�����##,�˜���+B�ð2@�@u<w��#%j#2'��=�:_}��JT������&B�x .���t)��cP�� �)#���3S9�335"�`�����+�#,Mc,�,}�*����g����$�ᛨ���B员�s�i �:CC<���Al#,SA#,��� ��#%j'�?����ğς�X��@9@�W��!Uڵ��W����c+��p�]=z�I�)2�۶I���`���Xj���\�nwd���nc)�%u���5�z֡S�l�H��O��m#,S���,��)�f�u�I&j�Mb�2�SRZZ�i�j欵��ޙY��u�.���aG��ך�j�45�覙�]a��1Վ�A��PJL���g~�t�F���mE�}mm�_�>;^V�r0O��L����MW%�?ӣ�ɺUb�3w��{��������ҍH �;B��+�j�O���WH�g�]�JK�k�][�C��ڟb>�N4��BC�!��Ж�`n�M�5t��F�i;��v��v���.�2pD�v"���Jw�["t*�Ֆk " �-��G�L���{q��ln;��j�8��V؍$I)���2��2�(��<z�MU���5��_.z�̿��19l=1IAJ~��u:����/Cߒ�D�oY���|���t应�۹7�I$I2@��~Z��nԦ�E.50 j�m����8���,��>����ю���dc_dD�v�����~��Q�������h$��� ��nG��M��@#bHS>��ө��d���*�%)H�)�#,�M�#%��L�D�qf#2�#%^�֖T/%(4��*&G��mϓ\CsJ��h������'�����,B��7C�LR����Y���N��7ͽ�Al�%݃#,p�C���6�9�f��D�B?aqg鳆8}t9�#% O�=~PY6���y \�x]��[p$ ��|�a2�'��I����a-�z�RϢ��*%��Q<�r0}�,�Q=}k���Or;@q����z��Ya^�f ����SA��\�;_x}�s��XƜ������;�CeS�]�`�~p=�͞ �����=❤T���;�����$�d�k�<�H"�N���w�a��рlz=F���+Pg#%s��Jm%O�m�����ootC�X,�HE�b�}��M~AgZ��t�w�'�Ƞg��������7;���Z�>`t����7�;8��������/�r��B�c��}�}�_��`��\�ε}���ZP�@�Aɲ|�"n�#�pWo}�h���!��\`)��U��.*�c�} ���P�X��t���#%�|�J��"�}}��dvj5s�B��r�%~�� ͫ�hj�ӕ�ȅ�̽��1�C"�lҤ.O#,�@�/����r���T���j ���0�1��Ǹ���S$��<xuXC�s�8郋��,Xz�Ϙ��8�S���GT��v�^�x<��>�%Y�U��ң�%�� �?\�mUM(�8lk#2���~Z�٤�Β�tj>?%0�15Q�$��T��uz����2цb�X�#mh�7��;ޢ�&���֛:rs"��U�?���3�AdV@�u�iNIZϿ����T�(�/��w���oAv(�T�߄����{����։�4�4�7�=�;w�Y|�{�������Kh��)�Sj�E�x�����ﺿF^���|��8�Xq{��E��%�����3#%�"hrO�*(�(W��#,��o#,,A��Y�i�b��mJ���j�f�����?Ծo��'�>�<�09�⁚S�^����J�d�[��UVԑ�*�#2?�L���w���!��(T��C���x۰�����#,�n��$cU HD�@b>jx�#�/ɒ.a.pX֨�W���(��N����z��6�0ҿO;�ɶƟ~r����F>z����c��=�)J�#2G���fg�+@����n8&YBt�o#,����~ͽ6��q$�K^�cEZ��:F?�h��Xf���0ޢ�q���s+P#%m$�uT-�#,C���#,T�`H���f�T�7dShɈ"�2\.�%� ��E�F*A�J*�"9����ϒ#2#%H:&�!��k�;�������%�X����S:���A5��:�@@�H;I"�Wچ�����M��zu%����v#AfR!����^��S������FiV}��3�������oS����S��#,��F�L�#7˼��(�*�+����#,� �+-����J�(��Z�,P��)����|?N���3M�����A�};�`%��:{�� ~�@%�I�"�s}~o4a�ؑ�4��a���M���i��B�K F#"0�P��%�8T�C�!�tR��}(⥅���R���;+Ó�xBJ<�:/;3���[��i^C�#2@գw�ܟ�}�RN5�7��n:P�����Q�@��m(����ɤ���z3��;m��m�9��"�2@���B�h0�(�=���vv����QY���縒'�7KK��((��骰S�#%�<lBO2J�Pvy��S��}wO�?¢B�M����~M�{*T?� !��6}�ЫKL�oL�a���0��_�qd�d�G���|����˳Z��A�u�e�/ !E�S�7�>|h�>� �#�G<�:�#�Y9!|��j�<�#,���eBV�G�#2�o����*KH��ٷZ<���C$"4�����%,~�(� !�I�C��0�����@�t�$$xˍ)�B0���o%h��þ Ȭ�b����z��W�@����١��gq#���#,g�Uq�|���#,רK!������,���B��{OVg�0vb��(�! 9)Uh�<�x�p��O���o���"���;T�%`1Ec�2 9��&K�p��q'P�&1\�e �E �*�)p�H}N4���_0���ëKe��%��ZE)`�\\���`��fn�X�A��@����#,s�Ӗ��f�y�#%��z���<�!R����Y. S#2 ���=�,���^�=cاXu�`pz�m�S��������d��S�9YRx`�d9`1N�#%����]DPI(3B�����Zw|��o%7y�}|�S�ުM�Of � #2�� M=X�o���%�,' �;1`���+$^Dy�ϴ��|*Ȝ� ��V�t�� �b�^�ݤ�lI���LF$M��(�/]z��ps�k�v?��?�T�t�#l�1绸UgP=`��*�I�d�Q]�TZS�R���l��/�p� ����R������������V���=��Wy������ȝ�),�I�U��k!��Lβ@p�(;��Yt�b'TVA�p���괂T<-�B{>̮��e����9 �p]�-���h��z����EM`�x'3{q�b#6�$�! l #�F��Kq>P���y�ww�'RznA���� �Y�TKH�s��'3�۰�5#�J B;����}{r�TrJO0��B��u��S(7�b���F#2Ґw��I��kd#2)r��}�����y2#%~�}ݞ�?�ii���2B�5���-���Ze���������#,R��&7�o���h��Jp$�+�_�G��B�N������1q�?������Oʀ���V�4f?���`���W����-Š[� ��N�wB��B8Tr��K\H��yF��#%]H+.��jР��4Ù����2#,��a��:B�l���~e��gY�b p,��T����w�*�oF`>�ʆ�?�+&|"H��ȏ��{ì�/rm^I��ܙw����L���6#,~gY���VmA�����^��z�]�*�� �/�̯E�gت�$��dO�¼���;���-�M�B���`�4�vX,�d�"�[4��G#%ra�hh�����=�Y���<��Y#%#2����6���yۨx��[i�/�h�!���[w����u�7�]��m�B2N;���b�\��lDi�د�����~��R�(CX{��7���^�B��VƚK]����E{�Z���%���a�ݨ���s$��f����{��Os]V��oC秶��34�@]>id��N��>�����#%k�a5/��g��< �6��8��_~¡!&�$�t�p!�����E/o��GSq�:-������DŽ��c�k���*���&ˑ�~��U�A��?q�,Z�t��v�=����X�#,�"�C4N�6��J�alU6� d��c.��@Md�[���9�����|�*��B�zN$D~aq��Mb��<߭�(j��G<��#2k�Q�ڎ�����|�Ӎ���R�����<|?�6�?f�O� ��o��5�>����9@W=K�!݄�?#ڋs�˷�Q�^p���G�SY������#%���O���k�J��&��8V����7� Z���I��x��*1�B�O����P�@Y#%"X �,']Y#,YRܠ:���?l:�����b.�wU�$pG��>�~K���MXkB"i^[]��ҵ#,|�I-���\���9��.�"A�xm���+0؞�8=3L�b<�DA��7�#%�J����._8������_�"�����#,9��e ���6�Ň�h$��\���:�l�R��n�F�^'yK�����6�����&i��jO#�/hq9"�T"�#2+�Aᩅ����q�������?��f�jB�f~��*B��c�aj1���[������@U���Rc'���W&]k� �g����f�P����h#{�[`;.�n@?��B��;HSz8��,�%:������?���ٛ $AfW�Xl^���t��g�l;OZ��X�$��|�J��d��Ӯr�X/�i�vg6��o��w��[�F/��Z�q�|�A�Ih�[H�N53]���!�cB��|s�V������`��O�����l����J�.#%M Ī-����m�*��������@�vG���D#��5��c��N?_B���O��a������kEQ����`n�(@��f���*��>�>V~�� �#%@#,c�)��(v�c���2�!$���߮b^��U��a�;qg�r����C��QfF[�����@����/=?m����}�c�O�!�9�0O��ӫQ�#�w�2��I��?�v`�#2t�q#%��s[���&��,�.]�{�י6ɾ�#%d��*6<}����8��6�5�{Ȯ[#,��_�c7Y�$���l�j|���j1O�yG����h����2Ysxl"��Χlł�;8�\��#2o��K��^#,�l�9<)d��E��ڥ��TM�0�#%�A�cA�e�ǁ�=��)�1V6D=�)=�b.�w�N��5�LUl(?�w��B�<9��@���Q�To�����Q��T�th��gc�Hm�Q�O�Q#%r�rz��p !�|��ͱK��U#2���3 ���@�Ƈ{�o����9����zeڊp��7>H��h����L#2r6_����u]C8����(M��T*���>�~u��Һ�9�͈Y t����V �q���`1��:`��o,0���>Ү*(��X(�>��G��X2h۔lՖ۷�F���Q���PAʽ7Uos��c(�|��~�����[T?��1� =!dy��E7O�x��D���7�Q����D������J�9��W6W�^!#%me~W�9��E��0{}#,%{�U:V^��B4���:���Mս�;O KM]~r�G7�j�PƱ/k��;tN��~g����e��10(7Vl��-*���5��r���J������y�ى7�ԝg#���������ԱBt:ȲX�e��TI:ճ�멜F#2��vg#,t<�%��#%�ҏ~�3�0h\�B@3��:-0��W��</�f��o5-{;u��Q�Iqvs�ÂG�f�?r������n8�x�����7 �tw7v�b{ �"L�L�2�6e��C��*�>#,��ރ�����*f���WM#�h�y'-zjn꽕�m�)�Q�0Gy�-���m�PE!���*ж�~��+���봘[���@"@"��y>1�~izr���#Qf[;I�Z�2�d�9��\"�����D>i9�����D����'���7�Pu�}V3I��I��H�tO��������=�7���s��P��Y�0����N�����>k<�ó���-x��5UX��08�.�P�5{^,���F������1u<_����U<�� y���bi}{��ن��i�XO�5�(��Պ1���ޠ��NjП��Wl)oz����;".����v���m���?���=u��ը�]�����G������{�Jl�.Wz�f�>�OBb!3�:�+��Wl/p��D#2�5�~��G�dt�g��p�1�`�æ=�)���~�!��ǝo�q+#,��I�����Ƚ��1أ�I�P�� B5���\��a�лv�L�d��d^��e�ys��1�z<����;%���L̄����$T��<ύ�rt7�>xX�E|�t�ɴK˷�E�SC����G��Nެ��98�0�R!Ny�٫(�F�z *���(�F�z��Z2U"�6�3��nq���蘫�o�!�b֙&���`��9G�$d#�B"�!�窧�{#%�1G2�w�d@�O�����>O����ϯ�����!hR��w�8_����v�4�����*���������49��#%�^wB�}�u�iDL�AĵI�v}��������|���<SXi�K�����oMUU��OS�`�&c#,�q@tٷ8@�v���m��M���;t�#2.���Di�$�H���蜡�W'P���6<Jj�F�ث��L��uͤ#%�6ף�u���Ol���:�!7-�ﰺ��K5��q��қr#2����'��x#%xá��y��#,1����#,(�Ȓ����L�M�=�c#2fbK����4�0����kn�cr7,%��rg���^ӧ'P.�k-������ Bs<�o�J���w��sC@,,���h��e�;�.>����'��Q��k��|e�k���FD7r�#ʞiU�P�h�\#,�l�0����_�g�)T"j�H�:�.��L0a��a��5� �X���@��(���"�p����=�fѥw�cvq��q3X��E�6��;���ֽ�ݦtH#�b����:�ګ%@�;����M{�����>g��l|JŐ}��v���#2u��ɬ�������ܟ������C����ު�3�gv�u#%iĨb����M��B��H�ѳ��Z�ƣm�6ɖ�Q�A����\eŽ���A��!#%�J��!�U/&E�������fh6��7������:o:#����t�D���(}�RO��C�j�۳m��C����<��� ݱ�����o{X���B���#��@���.��U���n�����Y��*Ip5��ԧ"�1�V��C���"`�Õ���U��m��R�.���'�I�r�i#2���c|�%A��I��Z8#%�hc�q�xF$�h�ݐ`8��FE�T�����4ƃi�4TRϰ�4p� Ǐ������q���,�"^#%35��#,�n1ɰ�`��0�- hI��b�$�gn����.���v�)2>��wn�s�]��:#,o�oO��+�ª��M�CAM�wY2!���vR�CQ�s���fRPm^�e'k�}�w����b�N:�#q�^+ڽ�:�O$<<D/S�����L%��N����0���0;���&h�7Z�u�o*S�,�-������!�u� �/9�)�ĝ��ms3X��Ba�m�H|M�4"qr���KM���7C��'w�<�Q'�ow o�ǃ��Mjf[,��X��W�A�Y���, �Dd�6k�R#G����f�@��n�|���_w�ݨϫhp,�g`6z���a��#% (9���p�o������HC}�XDD�2D;O�����ۮ���&)>�Y��9����QP^^"S�bm�Gѻ��r1�^��W#%�?��0�u��&sZw�,A"����#,�!�.N=���Ȟ�>#%����sэ`���#2Mw��� ��g6Ӌd�hv��c#2�8��(�B���^»bhlw����,I�M��k� @i#�vŏK�F�2}��3c#2L7{I��#,�!ea���Jd���@GCԫ1��<��o~ŢTB�#,�^�6���'��=Q�>g��w�M�A���8m'��&e�kNW�@Y�N�Q#%ÑAR��ῂ����]�^0�Z��� mE��[�n�JQ78fM���`���M��%��ù.���a���y"��w'����i8YΠw�͍#,91)77,x�p�6dYӻ��Գ��;5�f|���iQV�R@�����|+ c�¬����7iw�F^�4B,s��� �2]�چ�(lwHAd��T�87�IC9y�e�EbJB�vo.S�d{N��ccL9TjEn$���2<I��M��|���N�k)�i Q��T�J�(�3ה9h��\�@ �+��53�!��ĩ�����̱�cYVe��J��3�K�궵��#2@��]q��T�\���F(,�X0zH��W��R��Z~�-�MY^l�nl#%��!�x����Ź���F���V#�t��2�FU8�RT�K�=k9��p�.�D晝y�]�!��6LϕP(�yf��0�53�r�әZ�|�Z��q��ݚ��� ����"�z��۷2P�A�'gϸR]�,�(IuK,Z�&Kb�Ҽv>�E��e�鑫<ܭHԢ�#Pb�,��%�/�4�kfsi�N$|qc��|�s<ꩱZ�L�]]x==a��rHv��4R��-m�`������B�s�'QQV�#2�!��Ԫm�<"����}28`�������^z�IA��#s���"���TP�s3#2p�s��7��������Uq���˯<�O�xm��E#%�����������-{u���i�č��v,�y0��h�Ba����n���#,��JB@G/��o�Jl�tkRkh��$&@�h���6ǖ\�X���6ָi�|#2D��nZC��(�/C�!�ə��ƪ������Bp����LBq6��<_�P,���#%9�y�k#2\!)�6��@�0%&d�����(���T�]�>#2`H��A�����b<B�#,#,�E�F<#%�%���E� �38a���Cq�t�#��#kkϲ#,���&6�E�F�#,Y��)t���z1�M)1�Z�TJ7%@�wӉ�$�gg����&�,��i�ȳ��X{O����9�$��o#,!���D�Cs#,���5�)a��x�T�P�sC� �C<"�m4�I#,�qɁ�p�#,f�M�QC��䏘��C2D�*M&i��(���xi1�9��֯P��Hͻ[�ˆ�39��5�����&�VsC�#,TA�k�);�5^��-����ܾ��7+�,A��d`���f���F!��\y�L��8�1Y�3U�vG��\�k���ku�r5��y����c�gGgr5��Hl^��R�eɺ��N��p�<]�r(E��4��y�F�Tb��I|�`���˦9��`���$��1���s�u'����6�1UEn��>�.����*&ͩ��5%�W�p�Փ�y�?#,\����i#,C��� n�E���seY$�L�#,���(#2 ?wZ7d}����m�k�2K��)��W��*e�f[C4���3R�ˍ��mS�2��bѱ����Ô�9�E�>��l�J����ZD���x�2|a����Ӫ�2?�b2,ó�|W�ǫ��pedt�t��_��rBn�oofz�y�AJ�R~��M�d���bѢa�� #,��6C����>(Q6��o!�UJJ�P�#2!`ʑ�>�kӊyw�+�#2G~�0s���z�Ї�~ɖa���N+QY-ܻƔA#%h���� M���mj~Z���R�fl�Fu��l���?7���%P�� Cî��E��i�����iJMR�d�)��PHB?�Ai# y O#,�A(��("�<|�MW��U�n7��M~�˽�\�bج�R�x�]i��T��PK3^����А�{#%��I )kخ3�%v����rA�T#2�j-"���#%���N#,���V�;��|�V_�U�;�$#�Y�z���IOH��5�����3.�D� ��h�@9����B"@��|�\�����*X4GZ�#,ʛá�x�{i#,�`E! �@�f�}At̬el�[�4h��xt����\fwV.�2�4�ԩ�#,ʁ�H��H]�I�X3�鄍�����"�#,}��yJ�ҏf�]��v�S�@�N]T_㘬;��������;<��X�H$���3�%�_��\$͕>*8#%N�Ġ��p5oMw��� ��#2�>{W��\�FG~�`6竖��?�E�]Y�"�`�@�M�S'��+�Ҭm\�U-%�J�mo`d;��;`��؈��� "�"(�#%Ȁ��q~a�������p��=N2Q�aB6��E�����Ī�������0�"�p�v�D4-^Y��W��2�ɚ��k�R�L[�ݼzm��M�nk�(�ݠ����-��y��.n���wW7,��ݣ�_.�j��K@�$R������Heg�_D� �&�#,um�+�v�78#%Ot����6̱��Xu�����c������s�̝�i\���';�sPq�B�>��r=��^��3�z��{�b�_��$||��_7�Mt��&�Gˮ_��WN��ٍ�G[�s>aP��+����ҭt��l�-;�@����U*V��cO�Y�M3���}28���g�����r݀ �����U8����_�K�GW��.#W�%٠p.@�f��Ġ��Sy�d�A��Y�JP��n�M�#2iaIq���b�bD2끰v��-����+U����b�x0S�v���M�w�ⷔ�M��HMޏ3]���~_(��,6�5�8*���`�w��BK�/x]�gf�I g�sC��E�W�<7�߫�^�����s4ꗫR�5m�&������ĩ�gB˝���\s��U����rLK۹�f���Q(�:�TOa�A_��̢�R�QI�������h��Q֢lOU&�^ޓ��U�H�4#,h���afjVD$}*���e+�Rt���I"n,ד��"�#,��h ]O��ͥ����3���Y�Y��]QWP�@���徶���/l!AK#)�Q�-�<���%HR����'֊���h-�J�[%�V4�eTb�YYmX�m��J�֒��ʍ6f#%$H��,����??W5Ĵ����d����7���9D*��2=~�>�L ��@��u���3�r�}�n��`M���nd(`<46:��#,C#�@oB>�C`*�"�����`��e:d�gZ�(�}բ?LR*��D3�'r�hd��H�t��M�#,%��hkI��/�ҲfI��s�r�w���*(�w*R�Z(�x�N{�up�&�ݨ$[j]8l�J�*ʽ�m�s��<��*#,YA�*F#% R��Du��LHT H�p�zg��"�A��2N�!HCZ���W5�L�R�QT���[HSQE'ٙ���h!���&��8@�#% HAdA�N�Uԣ���>}��z���ŹSM�20��w�@3 ����y�w�v) ��#%�H�}!C���C����/��~����O��U8>s��O�`,���;<x�,SP#T%��D#%-$�:����A��VD|�m�}�iӧ+.���B�P�P�?�(��$&ϷM.��[?��>Te4g\dKA~�S�mz��-V��D�)N���N\�f���ē�R+���A#,�Zb����i�1픉�;+.����:�u��@�>���CU8/��G�j{�IS�I�fQ��T�����zI�k�l�(2�h�5��M�O4�>]gO*;B�q@l�i8"lHf�I�BP�Md��G����~�i�v$���S��}������_�w����(w�~��7�M��G�U+�m����~���am�0~�%#��i�S���X����*�@���MA K��Pg4@��C�>>�#,�{�����5:�"�u!��v�#,�y�#2Q6ٔ�ҙ����c�L(�g���c'v��d��:Ӎ1��=c��Q©ƿǛ����mt��I[�A6X�k��*#2�.���XRka\��rnjh�X#%�FOqIQP���yQ�#%�ϼE�4>��6u�9�b����$!f9�?L��!A�)���ҍDAA�#2���Wޫ��8�l}�wv��(��HB'OO�h��P�+�4 �|gg�.|��3�������żԗ�tc\����8xȊ~_������р|:��)Ub�Y��@Ӑ8�,�������j�W�@�������ɻ���ڡ�A�C�*�n��⮴�,��ش^�r��2T��.W ��. �J{V�=ne�^s�w7��D���y+�����B�[k�zD��1�?�M��}�wL(��*�Gw����t�]�N�u���Üq���1в�f��[d�F%�;p�g���]��zl]�؈��y�EE0�7�~6ٮ2.H����#2���7yl�s��y6��m\9�7�`�WpS�c��Ʀ���S���PV;V��E�#�Ö�#,jw��h�R {(�Z"����^��[57K��l��0(�4|>��u����X���1�C\����^��c�7>������z�����)=t&~a�|�N�*{L0#%BV�%Q�D���R�/��x����ӣ�Z����ұ�W�<��'�=��z&��+��"x�G^�}�56#2�zJ��#2Y�"����Ϝ0b�7�P�����F��#cˣ�8����k��f��\���˾���!~��7zx�9d$#,gx�U�j�6/]f_��wѸ�۫u�oh���ؖ$�G5�n����;Zл�\n�#,�+�p@8i��}H@�m1���l�pnX���{(ͦ��Na}"�C�Pd��^DZ��,AF�����$L�9�4��O��~+"0F;4�ZU7T'�����p1�=h�)G�#,�L�Aa�1�z�&��t�ר�wN�:cn��SQ1�0U���KH�Gm��N�B���;�1��oG��1,�.�Ϻ&�\��I��G�q�'��է���|8���h��(r��}�N�T{榤m���"<�$I�����IS�;� )=Y�����F��0��&�aŐ?�׳h�FE5}\2�u�^��H/�u���ݓZ�(�~����� �[>#,D�p����:������%����N��l�\�*�Kk���廚dar�Q��V8�`�IM�%.ӗsw2#��l�5�#,��� 6��V GF��#,�-#,Mb���2�m�_�;����ģc#2l�ؘҳ���i����3ζ�g�W�ܟ���R��R�ATm%�U��2k6߆�𫮓�c���#%* �1�A|C�y$ &���!���{��خ�}yl)i�AaL�v� �%�y�ё���q����S�P��#2f�D㪵m�a�Ԣ���:a]���%�۬�e~�V���za���n5��V:���M5q�ym� ���L�������]<3�wZ5\�W�KD"D�H�#,F�$n:��B#2RD(4-*,)E�a�I�[E3#%���>����0B�^��_\�ƃn�Xڊѫ�X�DR`l�I֘�"b��[�z뀼���ם|�[T�M�5������x�$�&��(��`S'\DPij�M���D�-n�D�|�iK�6���ͽ�b)"D�ݎ!\57��������-fvc)��m���C!DgrB4� �'���#|�utF����b�������f���3~#,:�1�*�!s�����;����DB���͐�T{����B��O���b�'����F̆���H�z�B$Y��:1���WI\�b���w�����5���� >Bq��}9?���Ns��zk3լ;�~��{��'@�/K�ׁ��t) �"v�j7��[�W�%��xE��r�\�\�(�թ��q>�i ����t�3������3��v�,#,gb��N�&RI6/�>η�5�Z�Ȁ�0�쀂�᠄�]�e���46�ԫuA��_�J@�"����h]�,,�:!�x7 f�j2B��+N��� (�� �H���\��gÃ>4Dg��1 ��$pٖ�z��!PU�4����AM`�`���u�˱�ʒ#2Q���2B7��Eu0��D�y�Z�'�[x3#,Bg �c$)i/� �h!�qJb`b(�j!��[|����yu��%ԥ�-�_�9��<v�#%�4�p?dH��6���q86��;��Q���"�������4uh�m>|����of����B<;�:����>b.K#"�����R��C��{˙w�r1]�g��q>�9#%��'8\KX6Uo������$�dXÕpͯw����G�.K���np셇.�q�]�WY"�\���8�X��,��g�B&I�E�U#,���?Ȑ1P=J�R5��y�(�:�Kd<���*Y:�I�0�h�#%o�싻����Y}<�� � π,�`LQ�L�x)�`�jn��'��Qj#�%���N�^AиT�,�'�JU��P��\�T����b�LcC@!��V%�J�1bN~�"(��SW�;�H�@4�L]qB$w�Ύ}!��W�EI��6b���;Sk�b�ZFt$#lh�я��0��i��G�����b�6���Pʳ����kA�!I�x�#%�O���BB33 ���e�!7u%q֪�|3:�3��cC}Χ#,��#ξ��ml6�Qǧ,��2K�@�ߓh�b�D�B�Ř���<0�9#%�;�����OU>4L�B�h�W���(���$1��������,d�U����ly#9#2����^�F=����R(��C���8�p����鞍m�i��pMy�-A����؈@��� �B�X��l�HALy�Jj6��X�#2b*#%Ƒ��x�l��FS��#,cot�,{)ٍ�0X���7#k�ͅt�W&�ZI�?��k��q��xK5jH^�g�&�K�b&�T�"�ĉ1e�4�f�nH.��\y'�� ���3G\m�-u�vG; S����b,mg�?l�:���ed�Ƭ�dR����Lھk[�v�)��r�[(��!�@�c�j��\U7�.J�Q�j�GR��O�|�ph��q�#2�\�ȮQ3%�9��#,�̦�HV���j4(��m0�$�Q �L 6l�11��B����5�ir�������d�'D%TR��a-&D)�i4�JZ���#,Kbȃ�Cv��V��3+wF���d�.۹���9�ML��5#���#|���[�A����u��_k�aߏ#���)��ԅ���9] i]d�!r��l���0sA(j\8$~�@6��e�f�C#2��ݝ[�cqj6�fdQr2�)Q"�E5 v��!���v��o�#2Z�>v���h�ca7�&s:���2�s=�3�2���6�z�dMuS�\���bR1��+n[���f]��6����k�>)4+.b�$������e��6�/'��q�َ�~d�sO�ٿM�K�sj���w@�2�#��ٜ�Ho���d�X���7@�NC��r[=d��q�N�,���l#%S��q����'$}#2ר�v4P���t�#2 >A�X��Z#%�c>�m) �,,�57���#%�K�iQмMW�#��h�&�#2�M#2�^]0T������D#%�P$��,d5fh#.�b@�)@�`�"!�9�`M�S%#,��7���&&��Y�T�&�Tﰪu�,�o�������٬?�tg�[j����M�9��j�7����=�a�H��IL�����{�����%\��F�iT�S+֦����a=p�@��Ӳ�x�<��+_��IJ����<[q�Z6��\ڶƵ�ڹ���Ū��t���m���g����_��#2)��:I�m�z��L�p�L�}:��0݃��g�'��4�־���IA)�2��i�d������f��;�0���TM5(d���(�,k߷(d֓ID�V�#2d��3$fTPĥC��#i,��LRJK(a� ��QiQ��&S�4c&J��*BeA�����Tf �A�m1�% ��4��S�&�g���e/�!#,�m�`�����U}Lavc_�2#���8�vp�Q�Tr}�+��gX&���d�x.��q�S(h�����j\ �0���]N���ލI��(=K�6� ��M�K�6�x��Y�R��ؗnk��c{8�h_���&�7<��m��$��7�%�Bs-�g�ڒq���v#�؛l1�#*��*Bk`{��־�����,Lcf�dl�J�E�m2���,<�gLJN��#,��o*ŀ���(=v����ϼ�'*��s�0��,�1IL�#�1!�#,��W>��/�W#,������$0'q�G�����zz��"'���s�Ff.%Q��k�Ƨ�i(6k/��r�;�>�/Sr�%�����P����c=�J��F�Hb ؕ$I#%�ڙ1�����H�fQ�v�~})��|f��OH�:̢Q��O��lc��J��w�nk�w��<���;Y���Ph��#!�kI����U$��}<�ὧ�e{H����*t*.#2mf�9��t(G�|�Cll����t��9�#Xc~M��;t��>ɇ<G����p�$��,nm_&�ɂ��2������~W�c.[�"^7L��<1YC�u-�4�'�ѯ thcd��g�� ����OS��k��ÙxIJ��q�fi<��4�#,C�q���:�6����Ui���Wu�T(@1�k��3�"�T���x[nfe��RD؏7��@��#2'������^��svw�#%�l���9n����}z�Bz���o��W��`�q��>߮�����i:�$3��;�N#2�����v�>ޯ�[~�Y~��#,�~a�+O��b6%�'s�~rz4��Ot7WqK��s���g&����8�ZX{SaǓ8��m�*�ԩ+鰱�b�D�tu��e g>Z�2�3Ru��`�dxL��Q�\���I2�����,"@�C�\#%kX>��#2t�C���;>h���U����J��[*�.�T�+���-�f�\Zb�S92j�XR�W#22rE�N#,�k0m3��f���1csQ�t�Σ�CL�[l��͌�9�B�XgF�E5(Ԧ.3Z�H��X\om.t�fں�zsְ'�|JҔ���w���U/��B�^,3���7���Qæ��� �2�8�?k�z�K#2�jf[CՒf5�f2�U��=ژ�ݜa��gmgf��]iڃK�T�-������t���x3Fӕ��3��X��$0�7$��l�ؒrV�ғ�`���wߩ�&B�o�,�7#2��R[�&*_������������4�To#,�?.02�!�n�6#,�Ω���с�Đ�4�&:�JF��9^H�.�V:��W<CM5sy��767��L��L��$�g�-b���<w���;am<F��OK9�{O�b�0�cM5%ܚ������0����01�H�I�#ӭ4�5u��,Z��:�q�ޕ�h�M���G���s�О���|������NU��e�QoDJ��٬�L��b�>*u�n)��g@:wC��և����ٲ�o���mcX�G�|6�'�Fv(��n$�=�JL%��f���Lx�glhpI �S��n+�4�G`7���)�R�w�_<�0���^�P��d�>��llg:���5���%�GQ�vY0���ti�X� 2c�X8��"$�kfM�(}m���%�]���B0H�Ђv������MqdKZ��2D�CȹiawPPe�#20��qL,}��)��y[6ۍiT��aS�J*V*·��U�|;�k�L Be�PcUpA��=y��<�;C�Y���+�Yt�WΨ��~뜷y��ff�#,5��1�LP�M��Yz�t$#,hi��m<-�bmu:a���mx2��G(�0냮`�\6�%�C����j��f��q �ba�v��dHK��#,���?+��#,�� +DLzY�UoeS�.i8u���e�E�q��Y��ջ� ����+/I�#,re�먱L-�THl�iv3ss4tӕ�Ӷ�WCBn�R�o!�N����Q��2(dش�#�.G �u&p�-JO����0������\�b�B�fY|c�4D#2�v$7��F7w����"���!4�t���p�����њ����n�ޡ�,IL�cs/{�z�V�ʒ����1�S�[O�s5m�i������f�L�F!ȟޣk|�.�9"ffP�d�x�6���!� �\�8u|"��m�q�Kf���s%O6;�a5c|��7�$t5��q�����ne��dwvt[��LLLb||��1��3Ԋ-���p�*!L�E }��#2����?���V��=�'�d\r�^rV6�$M���e�4Kb�3�#,e����m�+k�s2�B�9���H4q�:jn�21�O)&PmV����\�[�l�f���5�,yU�Lb�0vB��E�h�tz�#l�[�K��~�2��C.|�p��,��pe��s���괝S���,V��N��a59e����1;3���T�'|IO�f�WG��|�&���"�P�$'I#%Ƿ�ڗ�@�M�@�S0�BƯ���0�1����Y2�F�&���ml�J�Z�5/Epf�Ǖ����=3��>��."qݢ��Y��$�h�[K�]qۀ�P����$8�)�[� T$�#,�GHؚ�5�}f��#%��7�I()^���5_^�#,"�&�T��;3��`�t�G��#��wb��hTk�!Kႃm�҂`6��`q�Br�dvl'�d��^�kJ$�C���a8�l'`���Ŷ2�*6��J����SR�3�@�0��t�w�)&�#,7Hkҫlɮh9���a2�D�#%ٛ�jɔ����" di���Jf�JE˻4�Z�N�(X��S7p��ͤ��C�sִ�M�RC��9$��iL7�l�.Dˑ��IŘx3�a��Jtf�05a�0�ƹ��f8� �v�!=��eV'���A� ���짒��6�у�:8D� �Q����p��r��l��f#,�To&�������z�.N'ZB2�9C��q+���Y�L�F��j��fcO���:[!͎ �@:�4cC#C8-Aon�4>ɫ �Y�U��q��/���}��FjP��L���І�45���0�5�������g��砠�+�d�C:8���A����P�Oj�|"ǭ�\�!`�C�F�u ��L�3[Q<w��x���ST)�P�RT���� 5��L�#I-��N�(ö{���(�"<#%�L�1��F6�_���0�\�cKY��,��E�Dv��J��l��q�>���#%T���ն�+��p:���!�!�CU-�%�iu�1`hq�y2C���fL�.cX��#,���k0غ�WU)���}��0��2,.���@�@m�Rd'��{��� �UP�C���@Cc�04p�o�6p��bIy���n�hg4g.3hn�"K�n�x�G�6Q�E��iuA�&O���H6G����P�,�v��ڹ�CX�2'#R��ͦMIH�GL�k�L������.�#,;#,���i3�-�g8f#%b���缾}<��_�T�ɚ2f�п�A(P����E!\4{3��6�k(\�>ԤA�����Q����j�{���$�22FI!#%'¨�}c�L�1�NB����F����8ԑ����P*��g�2�2�]��we��-g���@i�u��❲���}(=������pc��/y���YËK��W)L֍�&��[����ay�/��(U�F��u�͓)���\�s�'M�.�iR�k5����Bh7�n�20+a�6t:����<7B,����z�1�����^��5��4pu\0Rg8`"}� �R��#,S#2u2����I����J�yf�6E���,�B-��MD��=�h؍U��� V��*�N�qT"Q�K�=���5�d�z����m���;U~�#%7|w)(%���9uwu]���2����6J�r�S���vE��nW�]g���ìy��C��5��;e1ت;����~�#%r�x��}�C���P��H�j(��Q���q`O��n<|;26��w��~�2.��f`��y9?ce}�6��|X�{s/���'��4�Sk /��hiQ��6Y8v��o@�P�o��nF��k`�Ѡc�SLA-�%T��GL0�.֔��.e��A2Ac��y��� H����Ə�bf!�DCXu?;���Q���H�>ƶ�6��s������ZmJf�Tk5�mD��D�6�2Ѩ(�ŌW��գE��D���k�+EN�E+�N:��$�2]���v�Y��C��H�|�k��DK1L!$�8�DV����Q�X�vz���;���N���������f���C�rzM#,���"�v��T�Y���*Ʌ~ ��d�vP#2r:m�m2�3+���4�L�d��p��R�7�N(��cKi"�F'���f4j�]*�M�K�oB5L��כ&1l�R�#,�h�q�ip�h�b�Q��8�D͌pgܨEb��`)�8Yv S©H�p���$i0`_����0ޤsL�w߄��#2<�=/Rҁ�rL��ݵq�$��1���d�7a�P��T�^�J\�Z!Z����f2���tV���h�- nQ����S3���x����#���#MTK&B��f��:b�x�0�y�ӻȧbm��lc+A)aLDH�c%���dĕ�H]��H�~lA�P`�#%����4#%�}�����'=b!�S2�4LY�A�t�]'�m�Z�7p����H�U��NJ�## �q��]rg�R�rE0��g�i#2Ҙo�*#�|1)�7v��#H���Pފp�(e�\��#,!6�~���Y�f�o`�8dd9:pD��TL��H�#2_;>�a�!9�Đ�h�B�n�ܢ�ְ2A�}N�'.���N��YVᕣ����i8f�~>[/<��;�y�Y"��u�n��L3�RA�>U ��R��X�U��k�+�"��saZmC�7��R�ג�3�bh�č('<���;X�B&�[M"���ս1� ]����� C��X�)�(ݺ�d�����<�HB0�L2 ��F�����@8#%Z�H#2���-��06:��3� F�f�h�P(+�P�#,{B�g���Q#2�FdϹ\��R(�=���պPa�(=�`,\�'�Ά�|i�l!��ƶ3;�.?�h����}�u��Jb`FC�+�d�& �I#^#%��VōQ��mX���*H$� Kަh}J�~z�)ܹz�>*�ˑ��淔=}O��֊_N+�����ԭ^���]Y[Q�Y����ZI\�&�tӆ��J�4�ɕj�`teJ����i�j�m&��&�d��v5-z�b����3f��F�4��]2����m�Hm�|�o$�)��j�ޡ(ef^i��W%�����J�4�D��\5&艹��p0�Nh��SP�pJ4c:ڝo���!�F✩�Y���ã8��i֝1��s\�Xwܺ�]� E2±J|�&-M� 31�5ę��dgZ�3��m⪆�������� 5�䯙��)L�i��1���$�#2��c�#,T�C Kʊ��Zn���dآ���sL�g�g(mIA��ņ��c����V�J��#%*"�5�$b��hڲ�fz{Yay�/&�r�}��q�k��@hX2���"�6&�I#2� "D�"�5���P�*�HE_��ՃT�`���O©��s���=��QU�>�J���v�ٮ��^�sח��e��H�!���V���i���WV�I��w]wqI�W-z�re�i��ʼ�V�kp��i��1,��C%"G��F�HZ+m�c)m2�$,�ț5���5"��������ɭ,ʚ�4�����j-P`�S4Z����ā�o-��3y �+�DZSV��#2!�2.�� ��B�m76�.Ģ%"�QP�X!�+��D='q��z����.�kի�XR÷�@���45���fa����x���P_X'�لӢ��U�;4z��KS-��#%D�F����&d��c&�M��sLU<���93#%��z�a�T�s�Y:�t��*UR�#,bQ��#,"��Zm�`�n�)�'':+��.#{�硈M���G��iׅ���6��O���D)�5�r;3#%XQ�p���ȯ���$HZ5C^�=����Xlw0�#�7�L��W��r�Q߷�S��~d�/��ݥ��IyU�\��#%r���nU��3%�ܤ1�lC)$<�D���.��~��l���x3�ϱB���4@5��9��r����F���J���W��8�^"��jﲀ�&�j�ޡ��~��D*DBU���1����������(�QP'gR�?���P���T@��� Kt�vKQ���Ւ/aD��*�L�nkk�e�Md���ݫ\�m6����(ش���d��)TS��#2Q��u�6��a�hf4ěEj��4ON(��Ԯ��%��v�j����SA�S5��f���%�A���_������K���I�(�����ȒD�6��u��I�I5-��w�6&�i���*j�m��i7��Z���*#���-�W^w$�Zd��-՚���j�]�)��Б���b����ޗ��O��T�Cݍ*�o�ϵ��V�Q�#2���|;+�զ�j4��xI`�w̒a:}Z��F�S }����c���r�U����i�:K@������Mx�&��TA֨bA �$A�H,�F#%!��=�6����_�"-�J٦��l�DTd�0��IP"]P�Dd�Ȍ�[�D,�T�:�SJl)�iJ)��A�*ۛUE�֖�F�R�3�E E�&�Kmi�i�Y5�Қ)R�|V�(�-EeQ-%�(�JHQ���)M"jLѰ�1�b��a�+e��2IdhXԚ�j��#2���R��T����-$mJ!��i�d(II�&Ra)�i�����#TEY6��&mI�E�kR�dɣJIiM�Y[RV�{�ݫiYm��YjCIoymk�͛Z��Y+V�W�W�=�\ֽf��F�K`��j�%V�6�ѭ}b�m�>��8\p�u9XE��pR�UM$j0�R��Fs~لފ����O�p��j2{ἯAp7;�4ڊygI*L�#%�x�#�7#x�=�-Q$!�Ï+����*/�'��OD7�dz�!�>��(��W��ɍtl��[4m����F�GV�C%��J7i(wr�J�1.��^����s1���=�_f8��r�J~�a�"��6��1�0��CBGp)��]28��"Flk��b���]z#%v��C�%~��ހ#2��B\r��6j����Xl�r��b���{�PO#,y�6G$��`A�Q���$��s�D�b�"����qݶӳ\w� z�U�jV7�bb�M<Â�3�l(n�ؑe?R>�B�.r�)Vᲁn���M#,���!)i��R��}J�#�T蔴����1�>���ᵉ���� Y�#,܅$�j(�$�T ��Ζ�_#,���F�&��Y��U&F5�P�̵�}!����H����j�Η�{��{v�b�]�#%�m�U6�<���S�����V��o(������"2! �D��K��5��t��z�Vb�$���}��JE`0��nx�Q�X�ipQRU#,��(�0���l4R��MMSY�>�$���@���o�Ӡq.�������q���7����:���J`���֚��#%�0>�V����$�ko[��Ǖw�������\���\G��R�dA]%�@���m|��or�أhee$H�KFsU@Ʊ�&F�h4=�!�&�Qk�#,�m&�=:ōbb)�F�I�ʹq�ba�qV Ց�M�V6p�P`۴�H�9�0�A@�@�in1v8����D1��U"��].�L-Z)�T��R⑿UI��#%/N�#2:�\�z5J<TBG���B)�5�5�N� �7��#,�Ct④T��`S���Gv��ͥP���x'�My����e�>)�0wy���sRp�ӷ�z�������P#%TF�Aj#2��#2__mn�?�Z��٩���H|A�>��� ��Uv.n�km�W�������c)��4��j[Ǻ%1����I9�0�%mŧ�֪žw�f���U�j[�mrk��i�Q�I�f�!�@�d�#,nj�RY��VTʁ��ߓ�f=����د�a�d ����/ �㞱J�Ͼa��U�c�C�y���cHd�H&@lFظ`V(Ė��Ma����V/���)})N0$#,qKJ��7~��rLڅ�~?[�Z�RU�����(40i!��:I�$����-Z�����5#%�c�(�I�1����s�s�gٙ�.�!�L#2�P�R3�xQȵ�x�ĩ`�X�h�N�����w�m�f�F����'3�GÜx�k�ii�}'S�qU��z��I#~MD����ҕ5�)�[�S>���"*̊!kken�kI��I�Lz�Q�`U2��힜q s�o{��K(����#,�<6�2#2��xd)`�XQ�O�@"��Z,+���X��0���x�@�Po�~�̈Ɖ�&#,��h�"v���,��j�7v���&�29m��ښ��5�$k1��Dzc[���ت��l�#%`E3����6�*�U�QJ�!=e�,��v�3���V��T.4�;�3sΌ�9�A�D��dB�4�jH�^��*�j�Ě�k�IXB�%��9�F�Cqp��G���H�Ԯ�]�3iB"s��"HҪq�A߂�,U���f�m�}r��Qꗗ��qS��8e��=�mY &&���4�.��!�=� �c�~�Kůu�4�uԛ3U1��z*]��5�w����v���n&p�y]m�f�<����~V�2����@�(I���F!U*�Ƕ�w��#4Ja�.��6����{�L��� P�'�u������_"*C�Z&��=��#�m���oN��U� �:�u�'�Ś��(U��ɰ6��B�*�K*ln����z�Cӽ5#2Q�p���ϨJ�:c����#�I]�X��A:����B����'n3�|�ْb#%��$OWa��IR��в�MdRf����>�σA���,�uODB�������Rqa�L/eԒ(� ��K)*�@��쉙D��^kի֮�l&�H� 8"H�:A(��:�3ۼ��v␚�s����.�)%�e# �_Ul2ÒD:#2;����n�բ���3Oٷ��P�9u�k5ܓ˭��=$��Mq��v$S��� �t�b |D�x_yu�٢��.�%���zB��ZF��Udf�d�Tɑ�3Ͷ�*+{�i�h�E�\�*�i4Ԯ�.m��ĖI�X���"��ň��ƔU^���ZPF_����U�H���F���7ĸe� �h'k�г)�Ɩ.�Y��!hE l���+#%����2��8A��`d���{��#%�ܲ�#䷆"��.���Zh�#2����HF�П>�N|����7,#�ޒ�@�<#,Ɔ�e�{����E�8G-bҔ<a���"��@��§�Uj��PT*�d�W�e�\��b(x�u�p:w�(�vG�UB��W6�k�퍦EF�h�� B�@ �7{wJ�#\$l����QxU�_(�)�O�)<�@B*�L�+(6�[�>|_`ow��Z(3��E��P!@��X�Z�0�?#,�3��~8�����k�Map.E�.�$����1���#%�!G�0�&?�ɤ�C��Ϫ�S`�;���l�������H����4@O�}��ŚH݆&�5�ϛ�J���Yq6?Q����F��aK�1#,�d��hOE�a��c<��@�hsO����(#2���Y�!��!]_f\^ިo��G\3�ш�YP��;u#%Ő�~a9�@8:�|)�)���gz�/C���w.;=#%�d#%RI�� #2J�*#2�DYX@��PPf��lY�!x�EdBD ��*�P�p;�̦["7̸�b?G���0V(-4�,̅�#2-�P��#��tN��c�{�~?~��X�"O�y��SҞԣC�'��^6r+/�0�$�$T�C�Dh�'�-��0����"���W#,/"�߫��>y��)Tbb�������p,�qC����k(�y��v���O���|>�"|��봯��J${�NYv���ԟ�H��T̉I:(�����V��t���"����"�������-��_�ᆌ3TAb��UH)��qML�)�U0)���;�Vha���h�}/o�\��U�-*D�9��$��u�*���ኒeb�mq���0���!�bY�dȂ��L�[\K�pd��P�&Qd���X��B��j�yQ�!�6��3+%hQ�#�Vk������BS ,��H�¶��)&Y#2�p��2S�PaD��Y� ��C �#2d��pƽ��ɵx����ֽ*��Rm�j�ф&!�5e��2�M�1���7Hڭ |��cx��l���1�+E��T=eX��A�F���P��J����aG$NM�r�.m�i]�b�nm��|�$ƽwz\hyu�|[#aH�/Y5M�h�ި��vp����aF��:�v�F�#,2�F���5fn�0�(2Ƥ��#,�0e�17F�H-kjVVڦ�ガm�D��Tx���#,���ds�}"0�I�,�3����-�I�R`B扭<x:���_��g�@���I���ڭ�v�ɖ�5��.�O��褦��h�~����������~��<� ����'�7�?T��h��@`U�W�������KN��n^VƥK%�ʮ�1�D�/�*��-UԬj�m���H��%�YPu��#%��II��n>�� �#2r,;Q5R1i��x���X#,Gꂤ@��Y���Wg�¬{S(��k���f�!��1#%�REV�(F�T��F1%��D*�l#���`3#2��(�<�]_n3��{@�r�8� A2T�����#,�z��H�*�j�SBm�r��)d��o;u)Rʮk��6��myfDQl��6B�=Mb�u]��5{(�̂���ѡBmRE��RKjMZ�4����#%�lM � TQ#�2<�Ԭ~|��!���$Z��&Q]��H#�#,E*\+�Hʢ�$�>�`@�#2H�e�`�ɖ@2��9$��㨋k��'%�#%GA .ʟC����1�����cs|�S/F��I�{W�$��\{��<�)�b���L����Ŭg*��+:w�}�#,��R#]�Bq.*��\W0�a6]�\��X7��:�\^�)QP��� �/�3��{���XU#,�unE�j!�=�`�+��ZT�v��%Rҕ5Xچm5�+�4�f��z��mbf�e$M�ey��o�}��ӷ�}���v����G��(PH�������H�>ύ�8�!y~�G�������tĹ�i�Zxt|�`�|t�I�m�*�N.��7/1�����CZ�h��S#,��3GK��\$��VR�E��pc#,�v�� ��Ãܘ���}�#%�(r��7���Y��>�� �)�z�����I$HI�="�?�72r=���Zލܴ����o��k� ����W�b��#2���5C-E��!l����Ȅ[���nts��S<0gQ�Uɳ�b?��51��G��#%�5��!$@C�1�Jt�ff�#�}l;���#1?��+�F�4��L ��# J ]�54�U���SD�Ct�~����jL�Y�p]!:@�Gų�U?ږ�?�����'�?�ɦ�'+��#%�M{�ź�5��kf���7���C�C�S�MZʸk2P��CT��������ڍ�5��PajJL�i��������e5��tA&��2���չmL�SdZ(Y��+f*��6�j�i��e��l�%�ZQM���5Y�i�m���`#KA�M�����������7Q�6N;�%��B&��rz��?�:K[�h�k�ʭE��]Mk\���#2�£���k�C�l$pB'bu�|4��6D���b����R�V���:�$�~���K�<�ʹ����ӎ0)!�4F#2}�?���>Y1q@a>;�VG������E/i�#2z<S�]98� (�T#%=��CC�����h~"���C'�Il���)�cr��-�)8R�� ����,[ǐ�><4�M���5�b� j��`TЏ�,��i�jClnIrz���6�)��u�2�^�30x��p�#2XXP�ȅp>w��֪p"wCH�#�:Ed�$���(J;��uwv�&�0jO����T/Wb�n��#%A�l��n�,ef ��0#2OtPܘpqC�K�c�F���V�"��!��А��$p��/�/�4tv���Yr����=�6ϔR�b�]C�ZN?�5��t�T/���}�}}#2h^0���a4� ��t����� ӅpMaj4����GF*AD�����Îxݿ��/:)y�$$=���~F����?a�L �}=(#2I�B�i�VB�e%,��-&�|�#,1�j�>i�.�R�EebRb��u����ψ0���@w��������F�֘�VYd�AH�x�@�B0ܶHF�aS�$RF�d_o�����)���`H��E)�����*#ӲvDIU��V�J!�� F�� ����0.�c֭=���/�P#,�3�U�2���6�bA�Ȥ@�T7F2��KA�zYn̲C<�ͦ�(�"b��#,0R!��5�5R��5���K�y��%��k����0�3��x���ˉ���Dpa�B� �d��7S�q#2Ĩ�(�B�\i����X�b�� Z/9��ލH�E�G�Di@�ȁB�!ICb�����BȔ�P�e'��#2z�<TC;4��?#2^W֨�:�?/��!�_D}.��'}U2#�Jd��"�!M��j�UQ�I�O�3˹@�x�4m���0�K ����y�`�B��f�Y��% �B������ƽ#j�0�Y6J-�1d�5##,p>m�3;�>09*(Nl�0)��e��Ĺ���MD�hFYH9)���}�I�ww`��tg�}\l�ȡ�k�=�P��"�u�2�փM3��L<����p���F�%�Hbz ��K#,,J�IZ��k��D�#X=<C��v%�v"|Jr+wt��}�>Ȉ��#,#,����\�er(�z�|���#%!^��C�ͭ�Ɯ_����B4�{�w%?#,��95��/���h~D$��߸��&M�e֔je 5VWE�[�$F�����B��N�x#�/t����'�7�@n0���L���5N�6��D]I��4^�/&sAn\\�(8#,�Z�#zJX��Ӳ�3Oo�ҭN���S�u�V�� ������i�s������>Y�{�c�#2�]Y��Y�_]#���c�����o���5ЁY�T�0X#%I#%���b$���T-��a@C�,Y,��"n1�l+p<;�T�)� ��ٿ�:��Uy�n�.���^�#%�j�5����CG�&,��קذ�@B8�t(�'_R4/���@nYGC���#%��<�p��:����@k���mCV��v��V�{�����@�_[��:���OB���ŜNl��^��E0M�6��5ʶ#,B����ƒBc#%@�I�m�, ܄��B\�)����Ө�6�P[C��.�խ �*�'�� #@!���]�~� �Z��0#2Ļ!��*ٖ�#2f1kR&'ѓ=����ۻ�z�+�.�p�k��X�0c#2�S+Ԗ��yx�]-�^���7��a�ZYl�VP�lT�,�C:E����^�M� �$AM�=(Mj��+��(l�YC�\m����tx&�%�FѨ� Hْ� a�X%���46��lJ���;��n���(a֔^,C6�f#�j�pQ���@_��qS��~F�Q����U�L��ݽ��}������.�@��}��ʶ7{�^�{$<%�P�#%�@���V��E�3�L�LJ�wuv �������Z5_�[}�יY���Y+be�d���5Jj�FH#����b��%!P*#$�}��ސ^��c�0�w,%6�6����;UU����j�T>Pr)N=G.;��O~Ye�U�O�k�>E���Y�#R&@���m���7��<�y�������m�S�W�?%�m���>��k}L��i��d�TA�G��#,����2��A�߳7؆V8����#,�hH܁���p�&/m����I �&��N���ŌX�=��^����$Ρӂ k���ro��1m�7�y�3�S-�Қ�{O���]��m�s�6�H_��;�m��#s�z�%��2t����1&y�r����Վ9�<��^�j�ݤճ�����*��>g��>����i�����`Rv��@��� �*hiaW���\�E637�#,>OrcL�ǽ.�'X�t֯<�q:��u�kC2��t�D��fsM��%�HTb���[���S�F��A��b�;�~Y����ձP��&�P��!/g�f�sl�2�,�s��g�|]��/ �D=�`��*L���B,�S��(����rf�����#20�Q��KA�Co�U��Q�tݩDa�/��&��������_�d���M�:���`�b!A1�L���$�A�u�b���G#�\"�F��� �DD��V/@�Vĸ�&�*A��Q�s7��:��\�C�ԜǨ���YV_����t�PJ�ŬZձ[���"��'�4�|�l��M�G���3��=���J�J��q4a�\!yNHRe�L�Һ6y���.�z i���0#N����$���-��hG�>1"��5e�%�zѿ��>|MB�w��$ E���� fhl�M� ��0����b�EJnNeEh �m�7�(��4Ք�i۶��؛[f��u[+����˻J�V�͖Q��J����m���6#,��xxC>�/rR��1�f���L��VH$p��Q`RM��|Rl<3��i>L� ���)�uITU���������a!}��)un���'1/��]N�h�_>�9\LN�P�3&r\4��Xv�pngS)d,�1��k��w���#����cÕ��net+�!�n#,�|r�2���{��#�8��ߴ|�F#%�=�����ޅ����r��yk���蹃#%Lq '[��<1��������+��v4U��#,@yJ��F�?>�k&�1p�]c�?jma'z��ɼ��m���g �״���O����{~�#%�?� B�':�\ڈs`�FN���E�HH�t��Ij��6�閪��kB�d� �����T��5���B�Vٙ���C֡p��o&�`#,B#2b��8۱d�S#,�.�.�xx�������}S���bs�ށh8ԡ�w� O�2Q9�x"�iѸtSH˥���{��|]����ٰ��<ʢ�*�W���5?6���&ᤎ�n�<yp��Ji����"&.#,����K����w�^�# sƃj���o�4�l^6����Fx�ܽ:[m�t�P��#2eИ�l%&�L��Hbs�A�e,t�r#,�����^HAY}�U�G��#2�L��t��'� ����m$1�#%��xFQ�����xޥt,d4q�v4�tؖ�&A�c}���[u��|RF��mA�+�`Z4{h��:��!幻Pmה��aШT%_o-U��t�)e�7�����k���?Y�#%:�"W���O#��3ǒ�����cWfێB�" Kv�sk��l^6�V+Qm�V�h�j�6ɍRkF�X��m^*ۛcms[k�L�0k���^ϣ���0����b)�?>#,ʫ�awI�ٴ�u6�v��g7nY�����;��d(]�)5�=:��}�m0 ��fݰ��t��\ �)���M]����a6� �$6ƳRj��f1�e0��^e�{S�u�i6ѯ��#%H�##,G��{s0P�l�D.��=2{}�z�uP{r��?'l�u��#,�l�c�e���\�;�L2� ��@q�^=v-}ą#T����E�T��u��g��4���V�`ڊZT�+f�-���`�&#,�I+o#%='�@�����[��{(P�;�����%UIA�GȒ>^z�g;���Ț�oAL�2e!р{S,���,�(S+��X�A�A��2@�$�B�U��a[#,aA�����fp�p�Pc���!�1#$ٕR ��T*���~�k�����˩���s^��4�l$r,&��X���!'�=u��0_,]�:gT9��~#2쩔;�w����\Z��r���*�&='��4u�g�C��-�'t;v3��psבb�1|_���\�X����� j��tX�:g���.�#,�^�����{��^�9��3D'��#,����]N~��ڴ>:����/Ԙd�P���u�f��Y�!L�2UP�`�C�v#,h)�%��e5'�or�Lo�c`�#2�;�j*(A'�#2BiHڙ��T4Z5�]F,hB_�{*#,�Qf����nBhT�ci0x�`hpU�J�0`�28��h���!�ѭS�� �LkLD��!��6��(��spH��W�3������T����E�*��&�E�%ZR�t��묙R�һ����OSn�����z�n��]KڈX^�ziP�� ���Z@����^J�מ5u��L�hA�[)Y����-I$YM��K6��26�KK�v��\�wr�ܐY���ӷoys^o;Ț(T���]��f�&��yz*F���#2��Ҕ<��A��Ml�VDe��L�̐�(`6X�==Y�cn�#,��d�Z����hj4r05��Z�,�F4=�m|��i<�Tq�i��@� ����3u�����4�pi�)��j�PHV�mt��#_�"A#,RP�B�#,9�2�j�m���d��bR.YA@�1��Й0�m#@20��-6�a�M�l�T�2�VDVm&!�#q�m,d�3-$��{]kƯ'z]���I��v�Lfc��0����8Dj0���2�a����p��4�������R�-�.&��9�����֤2E����`i�l(A����ģ��&��ҙ#%�9�[���#������,��]�%�c)�Y<�G�.�N'�IJG�����0q��֑��#%Ս4���5���1��U%Sg�!K`J��$}f�l8����e��F�%9�i� x����C?T� �}�Ƨ"�1�M���ݗ��d6r��ԝ<�A#2������m��t�Wъ�c�B�יP[i���ͲK�����f��7��M%8�k$4$îr�P�Fͬ4�j�Q�b��4q�����Ѿ7o�=�l��Î8X#PX�T��dBN!.�Za�b�`�r�n2�2�ݱ�� �� G�O8a�)� �P4-(���B[w������o.�SR�mR�X���lF�,���$�#�Av� D$���ЀrӁ��|CşN'��'������Ѫi���z���E��b�?t�h�4Q����i�&��ݺ��}�(ɳ�4�FA���JR�-!wQ�Q����ɽb��4<5���V�on�JYڸ�P��xSpT`VR������������_$�o�BiY<��Ο_�6v��Q��I!�s36��6o:+�x�6�&��RW��������f�#,��*��&c�vi"9z]#,r6ǽk�n���幝���A�=E�A��v��;}ոm#,���������Y��Sx�j1_�Vvu曞8"���{�P�X��곐xFpSԚSvTD�@#m�A ���άႻ��*5ĕ5�9��I�����`ش��8eh&��8�̍I��{�����\}(qH���Z6�U+|��mc[l��t������\ SSeH��T#2 x4lAR|ER�FȤm!�ۼ�V�ңx����6�M�M��tX���M]���v�C�^6��d�i���5s�껻V5�Zk�^5�����[���7�V4��A`!�В�=z_�У�a�I}ا3߄�E�$V�H��QB�F�Zb��� �]�RAw���A(�{����ֻ^�^L�-��@1���e#,b�)������֢*5R��"�Z�l��+13M*-�����Tlj-E���X4hƙ�M�̢fLJ��#jfM�3iX���5 0�n>XT�W��_��;$L�>}�k�Pi6@d�D�R��:l�䟓������Z^~|�����q�Dll�|��G)�XA n-����UH2>Q�D��Z7���7��Y�U�k}���V�Z��]]AhҞn�#m;�:���%-m�TUX�[s\����7gV��ez�٬�Q����v���7��w����,�>��$�J#%L&D#,�h�LA"#2�b#,���7��`Ij�!&�J:�Q"'#˟���Pm+��4�� ���Nκk�f�ֶ!4��� S�S�:�>-{�>�#2'�%�'��~��0u�C*"�}3M�C�<`l�y�G�����`��31���,�q��ew2M5 �0�"�f��tpI��<��{ZQ��xB�H�����7�>��aI�O ���4C����πʷ���1���a<�5���+��/���h��]�3a�8f���=�6��̈́%��{+�3�Fp�,��;]�R9����0`�)d�LK���x&�`��vб��w�$�s���a=�BZ�,�b��M���g千�|h�X��R���L�)�+j�b���a�6��t�!u���''�0��,���-�T����RcI��Ë��;b+�TnM �b�Ea#%m$#,��B���w�d�s�+�8co:.3�H��"����% t�L_��$�Y��A�� �"��(EE����5�-37lZRE������H���A�QVI�l���i�_l�^wU�Oe�*�"#is]��ZG�*��F2������K�h�*7j*�����X��SV�(1�*�A�XU�!R#,��aS#2$D�Q#2#2��,�ʎXI���aV��BB��L@^4��?U���a84�1z�������{�ʅ� )H^v{:!����O��kh0�U9�87k�s��R2qeĜ�q9>� o�1���KQ�n��������*���"%k_���V�j�*�m�쀑���C�L���B@�P�J3������%�a!�t?Bj�?<k�0�mC��`E�s��l#,7�������+[;~:q>�zXӐc�"<����WO���7�S6r^'o�k��^#,��e�-�/#%����8`��! �1U��Y��xِ��!�(�M!#2�%��(�f�i���6&r��#2���F�U�;20Ƅ�5�*��&��k8(�DR�%+H�I#%� �6�0��@��%ɰdX<�2�^/�#%�ez5r������%���;��>�Hש���7�9���lޭ`gĪt��$��S�����}s�<� �� �USE2@��J���db�"`A,����IB�.Grc>?�ύ�x��^BSUwU�kl&VvV�1�������2|��,��n�]PRP�)�pҎ��^CbS��y���dM$���R�x�v�d�b�f����\ەʹ�������ێ��s�r��t����<�G4�o'�n�]�fX���mR�v�\ܵ�j�m��Y��6e�d�[���t��Κ�Z3�9Wl��j-9Z�]��r�n���f�#%nn�؞����v"A�#%=�}[��r�����(#%;��pw��A`�j�� �('k,-����C�QM�՚�����#2���6�R#,�)��T{�a=a^��6{�|M+@>1/�Cџx���(P~>����N�Ӭ�!`��V5��5j2��_=�UA�%F@R�,���g�� #2�#%�ίw#2)��","��* bBh#,#��p(> ZZ����\�nv��]�K+0��^����y��́������%�%Z���BFcչn��)��&I�U�E4H�RQHCL#%Lst{n��I���-��R �#,)k�`&Q@��L`BA�.���{�12#2S�"��y��`e~6(La�a�b�C����5��jp�@֙��)U_}�b��+R͖�i�@R#%łGz��r����[�k|vٍdٵ#KL�$UBH����c�����/��{�(�Ԗ��&���P���@#X�.\1�D�t��jgm<f��#%=QRF�⦻) #%�Bw��P"�I�#29�2t�J&b��l���'���{#�!0�S� {ߧ��=��(M˭�#,`b��f�Jr.#2�hR$�MN�s�#,� �Z.�#,>2�э��) $��E!�N:���>��u?�K��:a���h���ܻ�hi�B����D�ʪ�#,�KE(,��H�PH܀4,*1h�r����F�ͥ��0(D@�#,d�L�P�6VjBTBW@#2�#,c0f+vʆ0T��-���-���SҮT���f���Mb���#~N͊��/8��o:�g>�-i\4��T�c3h~`��$.*��j��K�����Y%z�B��5��{�6�;cI��w���3.ZZA��#%$TG���JT�n~��ف678�� �WYI�v��1��P��M�#2� C]��#2Cȫ��:Q���FЦ咐�Ĉ0��(V4ݨTr�)�-P�F�kx�)���@���G��#Ij���^�4T#%���A`ăD�U�UNAk�V��[�~�S4�ޭ;b#,A�#PZ���t�g[1�� �s�xOd#,��y�GP�)�)��DM�p�~��� �6��ij���L[D M�t�g�!���U���������'�צ�V�;\�Z��6�����ɒc��$���c����vHEJ�Gt+�rf���lc������Q��KK�\�P���.Zi�NK��C�^�G�4C�"���4����hv�ڃ�#2�~���q؍��v��T@Ga�x(��d<�B�#2 =t4�Uc�"�C� �DC�!Q�Nɢ�E�)�v?|ž�N,m���3�#,���!�m�zL�?=)&�B�S4i�5��a6�|�#�#%:��������|9�}�����,��W����Ԡ��(Th�}U�u��)�op�V]�L��5��!9B4��U��-!�TQ�-�B2�6Pno���)� ���Y��Lm�(��T)���Z�;xxL�)�i�s\�6EУ�"c"�h����JeKjK�I�U���j 3&4hȉi<��|�D7�6(��9�?/������LEj#2b�ކw}~g__�4��H�)\j$s����^'bv�=�oi�sEQ��$�0��#�U9�0$�{��~*��#�Ͼ�����1L}�,�jۄ��{�r=��W�����z4����XӁ�����!d$r�6i��1�@�x `�[�Z"٭b1��ǢM&�T��}s�!�d�vg�#�^��lsN���Ď�Bē�6��>��3Z)E�A�<��gJy�����l����:�İc�=�7F�>�W`���Y8r�W����`�(7��k���<�-��a/<������\��s�#KK�0:��7�#,�}�=#�x�����є�xb��U�L�WK��6SY#����3���#��:@��bF#,��T�r�"��f)�#,���];��#�z�WjXq;��F?���Q������8ndwp�]}[t� S��y�+��p@���ٛ|���8�i#bf��V��6[k�H���a�bI��F��;g��#27���-]��K�I��S��q�KP*H�f�e��S���#@�h8ᝎOu�m���7��]����fj�|X��=���%l�MfG��&-@��B�߰�MZ��[Բ[ŵ���9�¦����+.j��j�W��!=g�K������*�����3��En�VW���z|4G�@˿k��j���]�ȶ�c@2N�R�b��q������B#,�1��a�GQ�G<��g�h�H��G��@����k�nxy}��N�G�ܴ�\�e�,<������4�tϰN�g���WB�C�H����Nw3�Q�L7H�ρZ7I$#,L���%�Q�1��}��2w�ER�����PL�@�tIz�$�4�n��D_}��>�P#,�a�A���{�J���e�#%D��#,}�0c1�����+eO�P��]� "��x#%I ���C�X_���#2���ADI�!dH�(wn/WAة���H�Wy�+�zS!����M��1��C�i�N�q#%��s#,An�#���ވ#��:��H������5���c�> y�+M ���/���9٫j���rdы>����(Xt��9C�Ye�H'@�D��H:c�W|�L�y"!��G�Ӑ+Ώe�W��+q��g#�s9eY�b�0j�6��lv�)�0�#R�0*$�=;#,�Sƭᮡ=��uj:�@���7;��l;��1��@q+�Z��������+)$��,�ވ��.?�[�ҁ��>��<C%PA���P�<A�ʘ~�!����#��9��q��[eRq�I~q������KPf��O�)r����J'�����J� 1s�U��;��/��>���[�v��/�>%���}v�3�?d������;�7��#\����x��!�'c�`.s�cj*����T�q�N�Lh1bB$�Z$չpc"�>8J�h\Rg���{��j�F��X$~YG�'���?iz*����#2�U1��RH�D�̺Ħ;�ۿQ�W8K�hB`�ӂz�6��yO��İ���=����P�A���o��?|��|�L��ڭ;�v��50@�:�~�}"�GJT�]��["@���P��l�9tI:�����lB�ЖLgJ��f?*�2Z�J�y9�W*��Uک4km�٬�T�X���SP�E���Ysʵ$���s\�.^��}�'���(��!�R�#%X"�����o^��G��<��3(ʒ#F`,�A4�%Q����(�F�T��M#2BM�&c!�$�����ɳ'��:��7ޛom���?X�$�6�A��a��h�3tdҊ��i/�x���頖@L@�5!0�#,�%������X0�'N�>�Kn,�>�2�Q#2�ԊF�Vj(�%�VG���oGTa�"P��!��bcm��1�.��[]4����>n���ܟ`��&A߬r���6�����]���B e�t���ױ�q�>ß��P�ќ��A/οPL����U%@�@��=[Hg���rL���[;�Q��2��|�#%�'����[����m��iG#%0NPȩ-D��#21u�2H���Tm�gu�J�m��7WZ����!�����{x�z�q¶�cI��d�i#���8�x)[�R��)(�m�#�R��5LƒM��!�M�Mi�x��W.�,�-$�Fr�=����\�mx3*��_{��H%��)fGH�.P���Z��#r'��N����b��.f�"�b�W�~��8Y�!q6� ]5���\(IQȆyNODj���덮#,�qFD�S�V�*�@ܨtQ��i66U���#,�V����B�������5A�����<w�n�]v���]ݮ�#)�F��f�&�#8���B�����m68�MD�2�mM6��M3�FSLlkp�%#,X�#,��nK�'\���Ir��#l���@��W��#2%]R(܉#2�p���i���n��J*[�%Ta���o#2�T�#,#,�#%�:o.M�y��n��JU�.�*.��U�K��$MT�c�SOy�l�2-�����c4Ng�9z�ƌ8�x��q!ع�R�U��U�� HVI�@��:��j�>��3OK �>U���c)Wi���a(� ��Km���E��!聽�T�#���(F5�O�4�A�7�2H�ɭIA�1�R����i�N��4�X#,/)�Tq�Z��F`�)��Z��j�#,�iQn��@dWc��B�64��b�^)����0�#,b��Z ��sȱ�T}f�͛�77|{ƬZ�Q�r��L�!ILs�C#&D�VE�Fi����(a S#2H���+Bd�2´*�NDb���w�PٗOK�ث� 3��!�̘�K���A���ء)�"��7�Q����&��Q# x>l��=�UE�8��a����L�&�f����M�g%FSE A�ǹ�VG���5�C��2#2>"�r5��W����}6�*16K�B/�֛�K#2����3+_�L��.�1�cQlBb8Oer{�k�8YX�E�-�6�4�x5H1�#,���]�`ŰK4�J�(�0�\����0�#,�(��!B��Q!bJ��"���4����Ճ�$C M�5$P�6��¡P�qs�ỻx���ytŨ�!X��'�E(�Z��D"���_^�P[Qm�B�ٴ͠�0�:ժ�Q�=�R��p��>�ݶhj�4�Gex���#%��B�",~p\�X������b�uꢏ��5Q=TQ�꒫2��G�H�B �#��h ;�(\��/a���%D8�U�b9�_�� ,��T"��N�+�`Y�/5Q�Z��c���#2����`z��X��b1�����komu#,� ���)#241U�)����9���=�4H��M�i�H~�K,!�����9�B��A��ADG8�/��������Bfڛ�gy,k�������]x���섋:�#,�/=���I�E�J͞&���j����n��k%�R;t��G>M�3����W�A+h��#,_��T�><��r�y�%C�˂�P�TP�`��N����x�����:����|/b�2A4<!�ʲ%u���{�H�?��b�|�ct�������^]�}��������^��#,��H��\9��M�q�S��5����:�!b���T�d�|�� 4��G��rA��Wԝ�d礇�콦����z�R��'j[b�r�#,v#%�ηU�����T71wV�f��m�Eçа>�N���F($�ȇ`�;�bY*Aeb����0���N�R�QmT�ޤ��H��s�k"�U� L�0�߉cYHj樤0��mE��-g��#,Α9`8��:i64Ir+�UA����D*"% "�RR�L�6�k�r�Kh����Kr������#,�F�����mm�VCXۛI������msgw�\�dڃj��i��#%��0�'{,���Ny�`OLCTW��8�fk离ᙉY��6�C�d���-���"CtE� @�M�C���.D@�I;��o���f���8��/��#��~`���"(�3M`|g�RK10��'��blL-o����!D��H�JF� Ɛ�$��逑^#%�c!��T0�U$@#,mm&��kC[]&�i�t�-�K�*� v�ytH����T��&�F���*�D?��>�Q�#�:�G���#%&�܈y�RuۡF-P��K�2P��HD��OE�iA��C�BR�@t#%�ə~c�?��bD���R�n�3�#2��@�C��j�tp$�(��&ںڿ�e-L͒IJ1id��i66hmIEb��RRJd�4)[h�TU����Դ�2ԴjeJŭ��!&�~�>u�ܐA�mֳ V�"8-8d)Kj�+�x0b�"�S��pcq�1��`D�A�P#v#L�G�$�M(�%y� 1&�QX�Cdc`D�Ik P�FL4�`JZ�QJ�#DQ�4����"�E��B��*#%-@�������wR��Z"�ۦ���ݘ�:��+��n�1R��"V$ �1V���;#%�t�\Eﱻ8D#>V�t�Vt�<%�^���K�Z(�QJ�� RD�`^�?�cdFnh{Z��P�l3v����,~a��%�����n�!#,�Z���0#@���0#2!HT?oN*b��C���B,���&��p���G�8'j��BID��n�ɼ���˩R��/һ�j�kbѪ�@$.#,-�g����?�{���)"0�2FnOW��6�5��w��T��/��X{Ap��!�?��?\VQ*r�.&�otzY�F"�`�`Ձ��R�ՠ�����J����%�MY��S|��|���#2�u��C����v�q8l�>����[,�0���\O���ʞw�[�c���%a�����҄��~����S���=E�h�&/���ۧ���D'܀��u��3K�.����x�'���4�n���%�f{ET�R!#%�����[#%]��o�c6:b��tu�0b�Y��|u\km�'#,����5�X�̪Ԯ8�.�#2�`f)�bm&ZYLĒ8�n]�=�����~c��7����wl����h�Hr���T2�!#ޫk�$������-k��BLw�7�d!��A#�7f�h���+e_����r��5k�$Iև-���K(�C�tSIɂ:@GH�\�Jm�6�8���}��%�7�nJ�y;k�Σݹ;,��)�-@�^��#2�lg�`"f�P0��]�A��w���Ay.N��6�mf%��&�0�.3K�) ���I�-���T�a8���3�{�����+!-c��%K��p����w�fI���V/J������g�p\���>קL�wI��O�Q�;`p��Tq]8���R�|�:���C�t42���o��x<,�.m��"e7�J���xm�l�2a$3��@��#,xzk}"y'�����9�R��^0��2.�e0c���I!��||�3�UY��!b<o�,pѾ�a& q<G&��S��ݍ�;hY�m�e�fٍb��lC"�q8�1D�l���c#%��~�#2'^Y��3�zY�mS�)]����Nʹ�Ù��>��}�.����М�^I'���4oSI�>%�+횎��H�K�wԇ,�u���^���O��F�%*1�mS�G��C��6�I��A�Ez֎��ƻ-���^g��}sҵ�)��^`�qq�$��a�w�)�s��8(u�<d�H9�����7���1�6��M�rJ���Z��(ʖVx������|ʼnt�CVo���.�=��$��#]^UQu�=��C���g�srXf��!߃��M����_���z �/f����_��W>������++d]z�c�_��=�M���%�`v؍�豋x<�9]t��9ۗ��rg��3;+�i�&v���^(mF��m<��9�2m��B��YM��*wa��#�U429r������k���@�2Uԗ.�L���s��a����*����$��3��W=��5�F�0d,� xZ��!�xi"e��6�I�jp��&Xw�x]�1�y��w^�B/�$gC���4!usJQ��S]�Ćhq3�q冂Z�Yv^A��0#2s�:L�o���l�V�Ʋv`�q�<%?UI�����Jfo8t�vp������#%�4����=t���]v�Chd�LC�*�#%�@=�#2� "`�#2�"#2��*Z�˖�QH�d�»6�e�zX�v�s(Z�n�U�������T�WY�Mx��P D�R�3Ս��L��Jњ\D��uV�6\Û��Q�UZ�# �����Dj^�&����'���*i�j��i�cA>�[ ��O����'�a3�a_*T�+9�����]'`�\�Σit��������gh�z�:�癎�����>�c��ET�QSSNF�b((�S�ۜM��e��{A�]��k]zV�4n����{#,�U��� �b���Iy[OD3�}���i P�XL�KC b_�l�B�m� w�{�-#�i�j�z#2ծc#,�ۭ���>��)�h���#I�9�̥�-�O���X�}Tp�(fy߉bP/]�7ZU��KL�o��\Ź�'L�<q{��V5�v�f����Q��h�т���r�7�}�zbn�q�j�m��<�Ȼ+��$71��`����]��ʧ��D�]zܷ�9���u�K�8�Ǹ��y�F�Y����������_h�L0xN�q]���3�Ͷ�#2��4vK#2z��p��B^$w۾ ������_�����ۃ�L�Β��P�5<���G��z�`rХ�K/V��#%�#XeAO�ATCKx�Y���u�SU��G���P;���'���" 1PК�]�/Cr̆��wG�ѓ�yt2yѴ�sV�#2�o�r�A�a����W+g�"l#,aO=gr&�9f�^�:p.XC;�mr�yĻ��0�͙pp��,�<���G7k[óT/ؖa�r��K��cӹl�F���Q�[Og:C�b�u*�l�A]�P�a \��ɭ��!eø#2���4#,�Y����qbBI��I��@�s8�Z�2�I�@5VH�p������-F�~��idj�6M����1菻�B�&�k]������~#>��ɱ?A�(������p>�r�0����:��ʕ﮿���c�~��}\�ֆ"^����{K`�}S�6�5J�>]|;�ɯ�c}��vu���=7�X��.l����1��$C�ҡE�|�>j a!)�����zc:B詡Y��1�qU%&F���Ġ=#� ��d S�kzkW�\�����h�P�U@� �4������V��55�U�����֠��A�ku�R,��`k����APcJ*"��EJ��ބz�o���7�9�ԯ��R�#%��?.'h���˶�/#,'I ��7Ӿ��9�W�&ƴ�ֿ*�5m�\��j���D/zN����p���SUh���}�X��e��R�9���c`��#2�D"5��j4�{nm������t���1h�]�2���M*�vl�8щ*�G�X����^�&�X��HRU�e!ʼn�A�Wˍ=H�wM�Y�H� �"��ZL�Zc�sd0�j4�M��I��u����� �4#2��T�4�N�n锎�B����3R��7�9#2-�uAH&a�T-G�$َ�˃�J�abnF;ۯc/MJi����e�܌��F�!!��X��ֵL�p��\y'[#,jǩ��9�eo�L�$1����o0)�T,Y�hX��x����j#,Y�m��3���o�js�N��4�XVC3����$H�`�І=�saPBP�"4�1a��ĶыW;QU��Gu��:T�y#,��s��[�#,+&JV���[1�L��L`ΰ4݀���=��Z�ҒF�F襳V�i�]P\��R8�F�0Tj���xH���1FV��.�CZF�L��2V8�jm��UJa�h�Jhp�6�6����ţo7�L�Y]�9�f��n]>t���*(�W��wV�J�CZ#DQ�F�f�e��Bᇫ�3`P��`p3D�_����e�<��,*F�eǮ)UW$y%�Q�%w��L ��ll�0�ހ��cL�"���b�[�cMUSW˄!K#2P�6�����c�kD�f�Ɋy虜�TD�ˌt�(�%���7�b��Lf#,��/*��"h���v���E�V��^f>��2��@�c�r-H�vS=�i�ǫ�5��#�9�����$)��o̥08�d��#,X��ih��#2���B1��<�FC�T�gAu2&8��ip�ĚlB��CV#2�ebkw�9*h�2B���F֧P�V06��� ��p25�o���Y�/A��g^ 19\��i]���i�����wu���S�4���f�PȑR#(�,��l\��>X��m�9�А#�+7O͵~�����5�v�\CW�t��p��(v�6��?!�'D)�$�:��ո��Jc-�?|�Pa"��dw��_s#2z�k��~.7VV,�t�]�I�{���D#,_��7I�A�,�Y�IH)0!�|���?N���ΐ� 3�y���*����̂ N[�95�6�0�A��bs�%b�e�����=Z�M+�F������F*(��*�U��j�FFUS�0�z��g����<�E�J=@r;X�ƺiTZH�]%��C[�����G�OD��yѸ��W �@H���瘢C�/$j&���IIWj�KV��\��*F�PlPPH��#,Xw졬��G����&�wW���~^�H��b�5CL��ci1�LcH�RP�L��ضKImX��lIY4hQM�F!�B�jF��$�f����41���H����h�M�J��-$�l0لJP�1`B*�����鷰���@'~���t5!���-s�{��s9�?4�]U�s@}��_���k�^D���<�8��_jז�N_,��IiR8�p=1@#2�9�G�ĆuCm��ש��h��;#��R&������a�"#�����V^��|܃���æ0�܄$4b(�a��XUSq���}�n�A�j�7=;��Q�j@�iN�}�����Ր�i�F������yy2��&�X�KX��-Z��cR�&�F)d$g2���!*�H��XA�~a�;����D�DT��ぺj��hT½�˃`ς�(TGaE�i��7?�5X����ơҢ���jH�&"(�ك�&����=0&��V`�Z��c��Z���bD�y�IlZ�YU(TF�����ь��6���&�q#,�Lb��P9k5����#2�]��A6�#2pA��mJT���fYd���P�Kő#,�|���-���ٖ�*@�1!E����F���)3r�o��85��������6#�x�m��b�UFƒ��L��!���Q��hN�3�đAB�R�]P��hl����"�p�#2K�H�[ɒD�I#�UlTCٿ��09#%&�&A��7��,$#%#2�v�S���ݎ�����~�#���z�g�)Q=���Q��ߋ�ɑ2uB�N�l�?4����t�@j�t�r�q���"�%H-IP�a��J���<�<�C�#%|���#2�Ȋ��#,���:�[z�魓�Ti���4Y�����6��}x��!K6j��e%=gȹ#,��L�̃K���j�D�h=�O�������9-�>E2Q(N�ЇU&��n�H��2I(�Ԣ#,7b����u<�9Z���Q�j����+�M��'$�k��^��@�W<M�q!"E��鬰��wwۗl�����`4�����SQ��**��B�#�kԟ�flS���/��T ̹�X�v����Rh�0��x�fs�(�ߥX��h8a6hZ�=��T�8UC2`�����t�@�'3��G� �V$����`��B��!�+��-`�H��\%0�����O��qYqt<%�f||�Cl5�e�m��d��vT�vx�3͞.k�c��"9��_���O>���yy����O�!�"��URa ��J*�.=3���X�Y� 9�\nc�b�S�2�!Ğ]�]���b2F��p���:��v�����,3�̈́JS�uUtD��19W�53��z:�����@#%!�M�&v�fD��@@5��U���K�ȁQT�Nr$�|���rkF�o��9&cq��2��rNb����#�Kn� �Ҋ5�a|j"3e�h@e/Ha�\��v�<v�K�~��:� ���"q�H���Nz5#,�Zu��%1�i>:A$��&�5�D�EPڥH��A��?a��A@��DL��6k#��P;S�Z��f��+a\�FP/#-*<H�K�!!� ���w8�D���T-��m�h�����(��L�张pT杦j��������A�(�����^�o�<�A��X2E�u���n����n�L�Ȱ�M�&�P,�KI(�a�vY�������D�uS2�cre38�t#%�a�%筻#2Lp�O��o�,��p]��QA�5�J]Hc�r�B�9���]haCR�d"�q�5jd@�)Iz����=t i�k�����[��Ҷ3��Ԩ�)x�Sq�4E̫��<����0e����;:�X#�e\$�<�,do�b9Έ#,a�]�V���<z6:kb�>x�D^�PM��L�a�\����B�s&���!�H�Ӥ�B�T�垩#��ñ�ͦbv� A�m���L\�RE�Fe�%o�ݓ*��,u��p�2oO�hNl�&#�F��%5�!�Ҟ�q��#2�t��N��YN�lmt�CHgP�1]0��Fq�Ț�!��^����m�O-e̡�HÕr���"� 5�;���#2�;���#2��-�;Em�v�4�h���d�4Z�:��} ��ʲÂY���s-�00�� �IӜ�+^�*f�zk�0��y���v'#,t�I��*�s&�i�t�ԭq�u!�h�5e�.W+#2�U��n�!�mg��̕*8����εl.��u�4�;��<��ؘ#2���ˁ�z뜣�WC�]&�&�b�(�n�H�&l����3���yt�ҥ���g��;�9��:ޡ�{���AӱMw��HF���ʎ��Ax5�-gD�L��X<dM634�1CMu�#%9�j�V"�"h4��N����Su�t�7�A�ZH�+��BN\��mgY��[6L���V�6�ľ�&���dYH����,i�?5ǖ�i�-����(�Ud�z������k�m��b5�h����.��m#�I�/��2�{l��M�K�ּ�4�~�L�t�#,�*H#2`9�_���p|�_���yScPC�Y�j��%=��(�v~zZb���\�kQ�~�<�'��}a[&��&�7��, �VJMjf��LX|r�X[[�#5�0CB���.qQ����ݕ���VM��,�L���K�c�k��ĦHk��]!7r��cB�@�̷gn�ՠ� �P�JP�H��q!�Y�%j�`���R�1ga0�Уh3�8��p����&&ڦ�,����*��`�s�����Y���k�|������ܜ�tEr�n\Z��4�3���;^PI��X�ga��;�̐E2��Ƀ7j$�M��a�#�r�hv]!�a"�`�鋫��5o�G܅����tL|0�$6d9қێ��I �捜��j`TnC]F&&g�$p�$�#,�*C�b���i ��CT�6#%}�PV����kFQ�b��4�E����@u��T�0�,�R��H�74%��]�TК���Y0#,#,L#%�N�\���d�E"+�������jMe�4Y*�n��3,UD��w<�����J-v���&.;B�Uq�섻Q�hYPlD��Y��dE����lY2�i����C}����Յ�K�*��lN!@��'#%.D��a6�U@���SP#,�F��m*����(��@SD]�,��mxri�S@ؤ#29�qbQH�`H���B���ei3��QH�X�"O��^}'�DZ��Q��eTDXkգÜ!�9l{��K#,C�D#%Hv�E�HH �UB���!�o��ލ��yg?]b�tW 셻f�V)�e�;�ƥ��5^KB�4F} �����0��9O�v��٫�jQthھH�J��6�ߒL#,%�21�F��+��QK�$�.C!r5�If���#%מ��*�=v�/�n��r�Q����#%p��Jv�fIM��N�:�Ï]���mޚd�<Up�w%Fdw�*D���e"diZ���M1���G�V�|�M2d���폹��4x�w�)���u#��*f�-_�)6�`��M��UV�A^G#nu�#,���{��Zcci7�wt'}e�p!>�=u�1�#2"ES�F\8?�C�[�L�3��l�r���~H���n�˙��%�$>�#%�n��T�{����#,�D�� L:{N���j)x��N�+FDm,�n2D*�1��J-�jw���n�#,�]�2Ę���BY!H2;�B�bA���4�bC��%?����@}�W��m�YA�:�nb�&��F����ѫ�M#2��$��,�Z��d�t}�>O��z���jg���Ø��Ԉ�'$��-��Z���[ɊO���F'�j#%�����5���#2�4V%vH��Ja^���C���9-IӀ����&�9w�#2nc���{c���xX��2p�m��RG�RO~�/����!�B'��J�,<��kr,A-�a�M�n\͗�1�s�f��}yJeV����CY�2�jj~��6�7r�p���!��")���=S6m��RB@^�+�4�8i�|.6�ư`��M#,u��{���4ظ���?�M��#��|aG���x��g�ʌʸ ��0�~�k��쵷kQIE��֔��M�u&�5�M�EGE��E�����{�P l����D�#2����QHR�.�~#%������*��j`p��K����6�l�M�Q�J��ׯ���|���SR�7��~�`�@$#% RE@����v��ƍ����q�g@�.����;�q֘��:��EK���kdq(1�I#2x��F6U4�8%�&²\��Q$Q���H�̳�[s��U���y�m�^��cVi��X��\�<ݑV@I�N�~��e��d���)�#%nR��&˙`9�Z��('oO3����c�������d����^��0���/e�t��U���V(���m�x�i�Er@1@!wN;�r"/�~���HI�d�S�rkb�|;\��X�{6�M�����AV�y#,�"��;����B/�QI>_�M2Lx��Z(�)�f�����d����m�#�����r���٨���+��@,q(b ��M��Y����Me�WӍ �f�D�J���|�`B϶#2'2� i��-H�t!�Y/Y�_{c韭>��w+�ܑ��=Fַ���z#,5��)�I�&����d����-fBlH�����Rm�m#%�HʉD�$F,R�s���<��X�员���aޢ�����: ��#,#,������X��{ya�&�$� .l��z�/��ٰn„�N�=Ǿꉑ�K�����W�Qo}��I���w�4|�2ᗂ%�-/PA@<M���+�S��`�)m��tc��I�7;p�#,M�I�qA�q�)\�����e�q�A���a�!�#28:� 7$�l�}uq��;9r�H�@li&�����m���ה�a�%�j2ĭ���l��mN�#,�H#%���c%�B���#,6�-#,�ӭ����N�����NോF��>c)��d݊�h7�#2ֆb�k#,���?c5�c,d_C+#2h|�܁#%�L�Lgo���a��K;�!J#%+�蠗T�J"A�������a:��N�1|ؗL�#2��6 �$`D`C���PA��פy�,|O#,��(D+ˑ��rlT�dZa�z(�+4S(��x�?x7���2J c��A�*r�]�>[o��֭�F]�Ϻ��GB����J(J�A-e2[���O��o���w�ڬ�t<���ِ�'�w�}��E���D��Q�8f��500.=Ԗl���-#,N�9��-��T<A���)��#����N��#-�B Y�*�1�.�b#F�.��$6F�_Gy�����\��7�z�-�$6L��!���Kɻ���Y66����帆1]ݼ[�+����ل_�#,D��C�T�I�$#,�[v}^��QAEWȯ��lj��g�;�+5L'����@1OE�`uu� $��X�1F*K�����2�D���TT�lmH��J�ͫ�~X�o�U�{�4���MEb��R������h����k��ޚ�@DL��JZ�z�9FSĈؐ䐜�I�~(�b�)�#2lkY�Thّ��V*e�'�;��H�@"��uҁh�Eޣ@�D���/ޚ����>��fyO| �Xp#22{��y|�T�ՙSU�XW��p���0�L[ðG��a�Հ������BH��S�1Ƕ��~7���Q* �):4Ϙ�Ђx���cy#2�F��D#,��!�{�|��0��[ԩ�B���0�tOr�BAy��*)Nci���D�� ���kT�RiI�[NӖ�ɦ����#2��e !�"�B�E��=�*Ȱ�Z̲��4���{���3�ᝈ� �j��W�`�[�i`M�ljh��4-���h�m!��#�����`�M��@s���5�y,`�6�z�oxt�/^Q��9�B�f�}ɨ.=��C��*��(<�ե�8ݓE�Ji�Rl�E-�T�5�I����o���l4V�6�H��ȢI��s��Y�,�B6�B��$a=*hU�>!sl� s*F�F&L(�QMCfҍa`�7�@��3�{�n�x;��T�������Y[Q�h6�#,Q�*�(�"�c�B|�G��=}M�l���Ue����q���!B#,�ᬱTa�\P�a��W,�5���؎����>�ęm��(ퟕ���[#{fdC`1a`�LLg}Z��x~��D�|Էh��oo��f�SE*[�l+���k���k��k�mMoJ�*-��7feW\ݵs��ȳj��ƚ&�wWw[I���i��M�YT4XXH��*�C�m��FƨІ�E�yq�M-�ԙe^����W^y֫��Ҍ�Z�e-y��v��E�2�]5�B�)�f����E��:qV�m�3��{���{�m,���_#22Ȩ�PL�Y�H$#2|rT1���zL��f�P��2�U��L�]u̒jsB�!�zUʏ��46 Y�%��E��\����䋈������a�b-а+��^01#,�oq�6��)�uF�����B�����>���Ę�"hj�T��|'Fu�x�i���[��30��S����� �Q�r�Fq/�}z���_��$��B05$���3U�w��3)#�#,r# P3>`Ӝ.rp|�M�p�:� �"`�#2� PyС��F�k���/�gW�U�foՁ�DѴR���k�|g��j� ~{7�;J���8b��k�E���{�4�F����8��y~�fk��r����(�Y�<�����Z��I-��������ӓ!�?=F7-�B`�ٷ[0Q�P��1��l���X�®���LPI��2X0�E#2�DC%��8O���a��Xb�#%�]�:�K��6��}�a���F���scF|�{�G9�����X�5h=�b�8����oV�Y��F8h��+-DEC=�vN�|���m�7�J?���n����^eB��#2V�ɤ3#2�w��hT1�5�Ä#,0��Kcb~�p��c�tñ,�#2��`��b(d7��IL��5��$$:(��;���vdl�#%Pl~FNx���������;�q�HH�����q�!�Ep{�g3����d@��e������Q��v�^��m<�Mz�}�%Q'݈������ ,��eAoU*#�l��)�̟Y!#2+e������*�q�,e�#%�ܲ��fk��5j��.*��Be��#%�O������g����~?�ܿ����?�o��������������x�~Oo���G��������_������������������_�����������#��?�������_�u�o�ب���Рy!���s>�����D�y; �e\?��iM�*�"���\��S+VE���e��o�Z��lX���-�~��Y���wQ$�&f}�+e[�5]�q(�Y��HVz5!٦�#,q�rB�)��Dm�쳿���@N��^��S!�iAsT?�-�<Cu����p9=��I��Ǒ^A�:��0�s�,{#%��B<��BR�?�PI\�Μ��x�`D)}�?}��7����K�=>=�#.��]�#,�X.�$0�x�4B@����_���Oü#,�oƗ���eN�&!2�n�3�[3?���0#,�J��!����n�4�Ʒf�Ghl���w�J�1�?���eT�h���K��<����R3�U���4²�ZhB�`����2������:���ɦ�6�[��Tu�g��D��U&a�]��K6K� �!��j}^}^#2�i�⑳�����8�+�^�{�:���p�Gꙭ69n˖(W3�$�$b1k��ؼ�@ˍ#%h���B#,�����xe:��սk�A�����#:Ӥlh�f4S���x�#2��M�{O��;�@�g8�����w���n�f�b��\�:"��q#�"a���]!��W����!�b�('���!J+��*{����rd*&1�X�ɚ�*#2�z�R#2��˻���~�f``3(H�&���p��&�V�"�� �P�;��Vl(bH�$`�$e�2���(w�QV�H1M�}>������-�+&|�9��2�gv�b0P�#%��ҡ���68���;�)��"�j���J�lkY�3[F�m����DŅ�S_E�WmU|>k_[B:?#�E3�y�|#%�]T�i�$HB��"�<Z�J@��P��|��7��##, �\���V��[�Ys#�fs��Y�V�U1�"����í'_��1#2��By�aE����_���@Z>����#%�!����\��joEw°5噫w#%��a��J������Y�D�<�t�fƨ`T����٨��'�E���Q�W8U|n�ch�W�����z���h�R��1�#,�� 0[��|��c^+I��k�ش|nmc�m�(��oSE�MAj��Z�U��<�vm�#%�\9!�ȣ"�FI�@���ọ�8����AD�S�����vꅘP�E<��$��e,��U�FFz�Z7y���M�`���A�H�#7b��[���k(�h�Gr:�o!|�`O�`�C�?-b��H��,X�mv���ԍP�E��:���ի����M��^�h �! H��� ������3����ڦ��"�������(��fYr0�m�C�'`���S�� Ȟ������ �H��k��I��x�$�EO��@P�_���s]9�YT���ȣ��- ݦ���-��з��m��ۤY� r�~���}�;O�~����Br�Tr�CΗuǓ�;��Og��� �d�K��70�N���_Eյ��g�c(�?t-A!��K�'痀$#%��*Qv�%?�J�H���\�]Dۧ��X���.�3��v��� }p� ��9�ɓGmGJ��qTE3�o����Y��w��M�N� gA�����X��7^[ c~�qQ-y[Na ��;��fJ�$� o�������"(�e�P`�v�d%�b���9���b��=g&(m��KUc��><q��SN3��7�~��#2����ܑN$��@ +#<== +#-----BEGIN PGP SIGNATURE-----\n\niQIyBAABCgAdFiEEivIt5aBoIuNHTzxwSbTGfAUneqoFAl5/EXAACgkQSbTGfAUn\neqp2nQ/46vvYBUDSJoGs14ZwZvCon9BigvosXc8by8ncPXNS1GIzbO9oxjjrK70v\nwsFrBJ+gEn4p4x2fR9yXuYcZr0mUVm0rqchXUJRAuwP8zvdDcYS8KZ2t34H4NarK\njGj+tRDQbBa+SmUcJvUFSnesdtm/OFAAJ1JayAzJqvoV9a78fenc3boJ7ag/v1+Y\nIcKscr5FIz4FQk0JBQa2i/DwvmJFlmP2nP589xdtRldbcQjXF24PxnFlGejGf5EY\nWtLPNl0WRSzgcMbN2O/aEAFq8TkCgak36fGeFcIO+2EqQ4Z03QvKwlA0JinmgJSl\nu0I6Pu/YHs3MvrbzZZBEtEhnxKBkilkHFNi4RWymKHBUOqcfpGyDIrDnFiXzoqcs\nsQTJ+Cv95Fm0xbcsiIFbNG/XRWcfvdk7bSb0C3VsVehWS+LyK4twXD9U7iHzPsLM\nHQ0oUqxfMwqp0NgwWeIMhSNROj3eYbHbgn131Dpxad4N5M3ajA/dl/u6T+qVkBh/\nR7hh6g+Q7FwxFyOm82uA0igZhRy0rCvIjpLbteAufA/VUjhSNLha0pYeOKTGkFXr\ndtmgvC77EgAN0lG0/76UTI2NRIeNevcCmFsQvT7/13gusIh/vFetPfKJxXzZNnAw\nlutXw20Mp9LcvdY/vSDCEqrQzB2bJsvF02jlRCGhkumrzEi+Xw==\n=y9ft\n-----END PGP SIGNATURE-----\n diff --git a/wscript b/wscript new file mode 100755 index 0000000..46ad72b --- /dev/null +++ b/wscript @@ -0,0 +1,138 @@ +#!/usr/bin/env python + +import sys, os + +def options(opt): + opt.load('compiler_cxx') + opt.load('compiler_c') + +def configure(conf): + conf.load('compiler_cxx') + conf.load('compiler_c') + + #conf.check_cxx(lib="glfw", + # errmsg="Please install the glfw library", + # mandatory=True) + #conf.check_cxx(lib="glm", + # errmsg="Please install the glm library", + # mandatory=True) + #conf.check_cxx(lib="openni", + # errmsg="Please install the openni2 library", + # mandatory=True) + #conf.check_cxx(lib="fltk", + # errmsg="Please install the fltk library", + # mandatory=True) + #conf.check_cxx(lib="opencv2", + # errmsg="Please install the opencv library", + # mandatory=True) + + + #platform specific + if sys.platform == 'darwin': + conf.env.INCLUDES_OS = ['/opt/local/include', + '/opt/local/include/libxml2', + '/opt/local/include/opencv4', + '/opt/local/include/opencv3', + '/opt/local/include/openni'] + conf.env.LIBPATH_OS = ['/opt/local/lib','/opt/local/lib/opencv3'] + conf.env.LIB_OS = ['m', 'xml2', 'fltk', 'fltk_images', + 'glfw', 'glew','OpenNI2', + 'opencv_core', 'opencv_highgui', + 'opencv_calib3d', 'opencv_imgproc', + 'opencv_imgcodecs', 'opencv_videoio', + 'opencv_aruco', 'opencv_features2d', + 'assimp'] + conf.env.FRAMEWORK_OS = ['Cocoa','OpenGL', 'AGL', 'Carbon', + 'Accelerate', 'IOKit','System', 'AppKit', + 'CoreFoundation'] + conf.env.DEFINES_OS = ['OSX=1', 'POSIX=1'] + elif sys.platform == 'win32' or sys.platform == 'cygwin': + conf.env.INCLUDES_OS = ['os/win/include/', 'C:\MinGW\include'] + conf.env.LIBPATH_OS = [os.path.join(os.getcwd(), 'os/win/lib/')] + conf.env.LIB_OS = ['m', 'pthreadGC1', + 'ws2_32', 'xml2', 'GLU', 'GL', + 'OpenNI2', 'fltk', 'fltk_gl', + 'opencv_core', 'opencv_highgui', + 'opencv_calib3d', 'opencv_imgproc'] + else : #linux + conf.env.INCLUDES_OS = ['/usr/include', '/usr/local/include', + '/usr/include/libxml2', + '/usr/include/opencv4', + '/usr/local/include/opencv4', + '/usr/include/opencv4', + '/usr/local/include/openni2', + '/usr/include/openni2'] + conf.env.LIB_OS = ['jpeg', 'X11', 'm', + 'xml2', 'GLU', 'GL', 'pthread', + 'glfw', 'GLEW', + 'OpenNI2', 'fltk', 'fltk_images', + 'opencv_core', 'opencv_highgui', + 'opencv_calib3d', 'opencv_imgproc', + 'opencv_imgcodecs', 'opencv_videoio', + 'opencv_aruco', 'opencv_features2d', + 'assimp', 'portaudio'] + conf.env.LIBPATH_OS = ['/usr/local/lib/'] + conf.env.DEFINES_OS = ['POSIX=1','GL42=1', 'LINUX=1'] + + #release specific + conf.env.CXXFLAGS = ['-O3', '-Wall', '-std=c++2a'] + conf.env.DEFINES = ['DEBUG(x)=//x'] + + #debug specific + conf.setenv('debug', env=conf.env.derive()) + conf.env.CXXFLAGS = ['-g', '-Wall', '-std=c++2a'] + conf.env.DEFINES = ['DEBUG(x)=std::cout<< x <<std::endl;'] + +def build(bld): + macApp = False + if sys.platform == 'win32' or sys.platform == 'msys' : + bld.objects( + source = bld.path.ant_glob('src/osc/oscPack/ip/win32/*.cpp') + +bld.path.ant_glob('src/osc/oscPack/ip/*.cpp') + +bld.path.ant_glob('src/osc/oscPack/osc/*.cpp'), + use = ['OS'], + target = 'oscpack') + else : + bld.objects( + source = bld.path.ant_glob('src/osc/oscPack/ip/posix/*.cpp') + +bld.path.ant_glob('src/osc/oscPack/ip/*.cpp') + +bld.path.ant_glob('src/osc/oscPack/osc/*.cpp'), + use = ['OS'], + target = 'oscpack') + + if sys.platform == 'darwin': + installPath = '/opt/bin/' + macApp = 'True' + + bld.program( + source = bld.path.ant_glob('src/gui/*.cpp') + + bld.path.ant_glob('src/modules/*.cpp') + + bld.path.ant_glob('src/geoms/*.cpp') + + bld.path.ant_glob('src/osc/*.cpp') + + bld.path.ant_glob('src/audio/*.cpp') + + bld.path.ant_glob('src/*.cpp'), + use = ['OS','ringbuf','oscpack'], + target = 'revil'+bld.variant, + vnum = '0.0.1', + mac_app = macApp, + mac_plist = 'data/Info.plist', + mac_resources = 'data/revil.icns', + ) + + bld.program( + source="src/utils/create_marker.cpp", + use="OS", + target="revil_create_marker") + + bld.install_files('${PREFIX}/share/applications', + ['data/revil.desktop']) + bld.install_files('${PREFIX}/share/mime/packages', + ['data/revil.xml']) + bld.install_files('${PREFIX}/share/icons', + ['data/revil.png']) + +from waflib.Build import BuildContext, CleanContext +class debug(BuildContext): + cmd = 'debug' + variant = 'debug' + -- GitLab