pax_global_header00006660000000000000000000000064121250673530014516gustar00rootroot0000000000000052 comment=e4b746b913532262e7254a7eafa4a7ef1b82aa21 scirenderer-1.1.0/000077500000000000000000000000001212506735300140225ustar00rootroot00000000000000scirenderer-1.1.0/.gitignore000066400000000000000000000003021212506735300160050ustar00rootroot00000000000000 # Java stuff *.class *.jar docs # C/C++ stuff *.[oa] *.so *.dll *.lib *.exp *.ilk *.def *.mak *.obj # other *~ *.log *.iml .idea loader.sce cleaner.sce loader_gateway.sce cleaner_gateway.sce scirenderer-1.1.0/AUTHORS000066400000000000000000000004451212506735300150750ustar00rootroot00000000000000scirenderer has been mainly developped by Pierre Lando Many others contributed to this project: - Bruno JOFRET - Manuel Juliachs - Sylvestre Ledru - ... scirenderer-1.1.0/CHANGES000066400000000000000000000224011212506735300150140ustar00rootroot00000000000000scirenderer (1.1.0) * Fix bad subticks number. * Draw the last tick. * Avoid to return subtick when no ticks defined. scirenderer (1.0.9) * Return all subticks when defined by their numbers -- Calixte DENIZET Thu, 28 Mar 2013 10:33:28 +0100 scirenderer (1.0.8) * Bug #12289 fixed: sub_ticks property was ignored. * Bug #12405 fixed: Floating point errors could lead to an infinite loop in ticks computation. -- Calixte DENIZET Wed, 27 Mar 2013 09:11:22 +0100 scirenderer (1.0.7) * Can change the graphics2D on export * Bug #11982 fixed - Ticks computations were made when drawing. * Legends were not drawn * Bug #12398 fixed: dotted lines were displayed as plain lines. * Fix various issues in the export -- Calixte DENIZET Fri, 15 Mar 2013 15:10:40 +0100 scirenderer (1.0.6) * Improve memory management on export. * Bug #2547 fixed - Too small marks were not correctly rendered in vectorial export. * Bug #11407 fixed - Exception with dashed line with numm thickness. * Bug #12051 fixed - Legends were not correctly exported. * Fix bugs (line width and line style) on export. * Bug #10633 fixed - Exported graphics were mirrored on some graphics cards. * Bug #11399 fixed - 2D plot with small axes were slanted. * Bug #12250 fixed - Export functions could be called before the graph was really built. -- Calixte DENIZET Tue, 19 Feb 2013 13:04:58 +0100 scirenderer (1.0.5) * Avoid "UnsupportedOperationException" when clearing ticks * Avoid "ConcurrentAccessException" when disposing OneShotRuler resources. * Fix export problems. * Bug #11791 fixed - Avoid to bind empty buffers. -- Calixte DENIZET Fri, 18 Jan 2013 08:59:49 +0100 scirenderer (1.0.4) * Fix for bug 11477: textures were not correctly delete. * Export: Remove artefacts and draw correctly segments on surface * Avoid to draw empty buffers -- Calixte DENIZET Wed, 09 Jan 2013 11:07:49 +0100 scirenderer (1.0.3) * Fix for Scilab's bug 11947: texture was not correctly scaled * Add a synchronous draw method for Scilab drawlater/drawnow * Remove memory leaks [ Sylvestre Ledru ] * The scirenderer jar was containing the examples (but not documented in it usages) -- Calixte DENIZET Wed, 19 Dec 2012 15:27:40 +0100 scirenderer (1.0.2) * Fix a problem with the memory cleaning with the Scilab graphic export. -- Bruno Jofret Wed, 26 Sep 2012 12:12:22 +0200 scirenderer (1.0.1) * Remove unused import. * Clear Raw Memory direct buffer. -- Bruno Jofret Tue, 25 Sep 2012 14:50:27 +0200 scirenderer (1.0.0) * Force ticks/grid margin to avoid big display density on small figures. * Limit Graduations values to be within Double precision. -- Bruno Jofret Mon, 24 Sep 2012 16:03:12 +0200 scirenderer (0.5.8) * Fix bug with NaN values when export -- Calixte Denizet Tue, 04 Sep 2012 10:54:11 +0200 scirenderer (0.5.7) * Fix a bug on the export of boxes in the 2d export. -- Calixte Denizet Thu, 30 Aug 2012 09:22:39 +0200 scirenderer (0.5.6) * Fix crash on scilab -nw -e 'plot3d();exit' (See Scilab bug #11508) * Check correctly the vbo availability * Improve graypolarplot rendering (and make it available in SVG and PDF) * Remove blue dashed line in 2D export * Fix bugs on Scilab's surf() export [ Sylvestre Ledru ] * Silent the serial warnings at compilation time -- Calixte Denizet Sat, 04 Aug 2012 10:53:49 +0200 scirenderer (0.5.5) * Fix a problem of display with the marks -- Calixte Denizet Wed, 01 Aug 2012 15:10:47 +0200 scirenderer (0.5.4) * Fix a color problem with sgrayplot on Scilab * Fix a bug on texture rendering, when plot2d() was rotated * Remove gray background in legends -- Calixte Denizet Mon, 30 Jul 2012 16:23:44 +0200 scirenderer (0.5.3) * Revert the "scilab -nw -e 'plot3d();exit'" patch. It was causing some issues in Javasci -- Calixte Denizet Mon, 30 Jul 2012 16:23:44 +0200 scirenderer (0.5.2) * Improve performances (390 => 24 seconds) on stacksize("max");a=rand(1,5000000);b=rand(a);tic();plot2d(a,b,-4);toc() in Scilab * Fix crash on scilab -nw -e 'plot3d();exit' (See Scilab bug #11508) -- Calixte Denizet Mon, 30 Jul 2012 15:18:01 +0200 scirenderer (0.5.1) * Fix some antialiasing issues under some operating systems. * Fix ticks precision on small/huge inner values. -- Calixte Denizet Sun, 15 Jul 2012 23:06:10 +0200 scirenderer (0.5.0) * Fix a Null Pointer Exception when doing in Scilab: driver('png');xinit('/tmp/foo.png');errbar();xend() * G2D export: Improve speed of 2D offscreen export * Export: avoid memleaks * Fix for Scilab bug #11407: Exception with lineWidth lower than 1 with offscreen export * Avoid a java.nio.BufferUnderflowException on offscreen export -- Calixte Denizet Mon, 09 Jul 2012 09:23:39 -0600 scirenderer (0.4.9) * User defined ticks rendering issue fixed (Regression introduced in version 0.4.8) * Transparency managed using alpha channel -- Vincent Couvert Wed, 20 Jun 2012 21:30:46 (UTC+0200) scirenderer (0.4.8) * Figures were not reset when using clf() (See Scilab bug #11268) * Objects ordering was wrong when drawing rectangles and polylines (See Scilab bug #11271) * Ticks rendering speed up using Java cached values -- Vincent Couvert Wed, 20 Jun 2012 12:21:46 (UTC+0200) scirenderer (0.4.7) * Ticks labels were truncated (See Scilab bug #11238) * Thickness property was not managed for Axes objects * Threads were not killed in canvas animator -- Vincent Couvert Thu, 12 Jun 2012 16:22:27 (UTC+0200) scirenderer (0.4.6) * Fix a problem with the drawlater * Add used DecimalFormat in RulerDrawingResult -- Calixte Denizet Fri, 08 Jun 2012 08:55:57 +0200 scirenderer (0.4.5) * Bad position for rotated labels fixed * Fix a crash when playing with export with legends -- Calixte Denizet Tue, 22 May 2012 15:04:47 +0200 scirenderer (0.4.4) * Plug anti-aliasing capabilities. -- Vincent Couvert Wed 16 May 2012, 11:40:27 (UTC+0200) scirenderer (0.4.3) * Fix a problem in canvas.waitEndOfDrawing() (Needed for Scilab drawlater/drawnow) -- Vincent Couvert Fri 11 May 2012 15:55:43 (UTC+0200) scirenderer (0.4.2) * Canvas redrawing was synchronous and lead to performances issues: now redrawing in asynchronous. * Add a waitImage() method for canvas to synchronously wait an image to be drawn. -- Vincent Couvert Thu 10 May 2012 15:01:22 (UTC+0200) scirenderer (0.4.1) * Disable DEBUG mode & add a setter to enable debug mode [ Sylvestre Ledru ] * Show warnings at build time * Various improvements on the jar * Add a manifest to avoid load of jogl.jar -- Calixte Denizet Thu, 19 Apr 2012 14:16:08 +0200 scirenderer (0.4.0) * Moved to jogl2 * Improve the detection of the VBO. See Scilab bug #10996 -- Calixte Denizet Sun, 15 Apr 2012 17:22:49 +0200 scirenderer (0.3.5) * Graphic export added -- Calixte Denizet Tue, 10 Apr 2012 17:22:49 +0200 scirenderer (0.3.4) * More examples/demos * Comments of the code * Coding style * More documentations in the source code [ Sylvestre Ledru ] * ant clean really cleans everything -- Pierre Lando Fri, 02 Mar 2012 16:43:42 +0100 scirenderer (0.3.3) * Allow texture rendering [ Sylvestre Ledru ] * "ant javadoc" target added * "ant all" target added * AUTHORS CHANGES COPYING COPYING-FR README files added -- Bruno JOFRET Sat, 18 Feb 2012 12:33:46 +0100 scirenderer (0.3.2) * Ticks distance fixed to have more readable ticks * Fix update on OpenGL clipping plane. -- Bruno JOFRET Sat, 18 Feb 2012 12:33:46 +0100 scirenderer (0.3.0) * Logarithmic Ruler added * Avoid duplicate FloatBuffer when not needed * Add Latex rendering -- Bruno JOFRET Sat, 18 Feb 2012 12:33:46 +0100 scirenderer-1.1.0/COPYING000066400000000000000000000511511212506735300150600ustar00rootroot00000000000000 CeCILL FREE SOFTWARE LICENSE AGREEMENT Notice This Agreement is a Free Software license agreement that is the result of discussions between its authors in order to ensure compliance with the two main principles guiding its drafting: * firstly, compliance with the principles governing the distribution of Free Software: access to source code, broad rights granted to users, * secondly, the election of a governing law, French law, with which it is conformant, both as regards the law of torts and intellectual property law, and the protection that it offers to both authors and holders of the economic rights over software. The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) license are: Commissariat à l'Energie Atomique - CEA, a public scientific, technical and industrial research establishment, having its principal place of business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. Centre National de la Recherche Scientifique - CNRS, a public scientific and technological establishment, having its principal place of business at 3 rue Michel-Ange, 75794 Paris cedex 16, France. Institut National de Recherche en Informatique et en Automatique - INRIA, a public scientific and technological establishment, having its principal place of business at Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex, France. Preamble The purpose of this Free Software license agreement is to grant users the right to modify and redistribute the software governed by this license within the framework of an open source distribution model. The exercising of these rights is conditional upon certain obligations for users so as to preserve this status for all subsequent redistributions. In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. In this respect, the risks associated with loading, using, modifying and/or developing or reproducing the software by the user are brought to the user's attention, given its Free Software status, which may make it complicated to use, with the result that its use is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the suitability of the software as regards their requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and operate it in the same conditions of security. This Agreement may be freely reproduced and published, provided it is not altered, and that no provisions are either added or removed herefrom. This Agreement may apply to any or all software for which the holder of the economic rights decides to submit the use thereof to its provisions. Article 1 - DEFINITIONS For the purpose of this Agreement, when the following expressions commence with a capital letter, they shall have the following meaning: Agreement: means this license agreement, and its possible subsequent versions and annexes. Software: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. Initial Software: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. Modified Software: means the Software modified by at least one Contribution. Source Code: means all the Software's instructions and program lines to which access is required so as to modify the Software. Object Code: means the binary files originating from the compilation of the Source Code. Holder: means the holder(s) of the economic rights over the Initial Software. Licensee: means the Software user(s) having accepted the Agreement. Contributor: means a Licensee having made at least one Contribution. Licensor: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. Contribution: means any or all modifications, corrections, translations, adaptations and/or new functions integrated into the Software by any or all Contributors, as well as any or all Internal Modules. Module: means a set of sources files including their documentation that enables supplementary functions or services in addition to those offered by the Software. External Module: means any or all Modules, not derived from the Software, so that this Module and the Software run in separate address spaces, with one calling the other when they are run. Internal Module: means any or all Module, connected to the Software so that they both execute in the same address space. GNU GPL: means the GNU General Public License version 2 or any subsequent version, as published by the Free Software Foundation Inc. Parties: mean both the Licensee and the Licensor. These expressions may be used both in singular and plural form. Article 2 - PURPOSE The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. Article 3 - ACCEPTANCE 3.1 The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: * (i) loading the Software by any or all means, notably, by downloading from a remote server, or by loading from a physical medium; * (ii) the first time the Licensee exercises any of the rights granted hereunder. 3.2 One copy of the Agreement, containing a notice relating to the characteristics of the Software, to the limited warranty, and to the fact that its use is restricted to experienced users has been provided to the Licensee prior to its acceptance as set forth in Article 3.1 hereinabove, and the Licensee hereby acknowledges that it has read and understood it. Article 4 - EFFECTIVE DATE AND TERM 4.1 EFFECTIVE DATE The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3.1. 4.2 TERM The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. Article 5 - SCOPE OF RIGHTS GRANTED The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for any or all use, and for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. Besides, if the Licensor owns or comes to own one or more patents protecting all or part of the functions of the Software or of its components, the Licensor undertakes not to enforce the rights granted by these patents against successive Licensees using, exploiting or modifying the Software. If these patents are transferred, the Licensor undertakes to have the transferees subscribe to the obligations set forth in this paragraph. 5.1 RIGHT OF USE The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: 1. permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. 2. loading, displaying, running, or storing the Software on any or all medium. 3. entitlement to observe, study or test its operation so as to determine the ideas and principles behind any or all constituent elements of said Software. This shall apply when the Licensee carries out any or all loading, displaying, running, transmission or storage operation as regards the Software, that it is entitled to carry out hereunder. 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS The right to make Contributions includes the right to translate, adapt, arrange, or make any or all modifications to the Software, and the right to reproduce the resulting software. The Licensee is authorized to make any or all Contributions to the Software provided that it includes an explicit notice that it is the author of said Contribution and indicates the date of the creation thereof. 5.3 RIGHT OF DISTRIBUTION In particular, the right of distribution includes the right to publish, transmit and communicate the Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or free of charge, one or more copies of the Software by any means. The Licensee is further authorized to distribute copies of the modified or unmodified Software to third parties according to the terms and conditions set forth hereinafter. 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION The Licensee is authorized to distribute true copies of the Software in Source Code or Object Code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the Object Code of the Software is redistributed, the Licensee allows future Licensees unhindered access to the full Source Code of the Software by indicating how to access it, it being understood that the additional cost of acquiring the Source Code shall not exceed the cost of transferring the data. 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE When the Licensee makes a Contribution to the Software, the terms and conditions for the distribution of the resulting Modified Software become subject to all the provisions of this Agreement. The Licensee is authorized to distribute the Modified Software, in source code or object code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the object code of the Modified Software is redistributed, the Licensee allows future Licensees unhindered access to the full source code of the Modified Software by indicating how to access it, it being understood that the additional cost of acquiring the source code shall not exceed the cost of transferring the data. 5.3.3 DISTRIBUTION OF EXTERNAL MODULES When the Licensee has developed an External Module, the terms and conditions of this Agreement do not apply to said External Module, that may be distributed under a separate license agreement. 5.3.4 COMPATIBILITY WITH THE GNU GPL The Licensee can include a code that is subject to the provisions of one of the versions of the GNU GPL in the Modified or unmodified Software, and distribute that entire code under the terms of the same version of the GNU GPL. The Licensee can include the Modified or unmodified Software in a code that is subject to the provisions of one of the versions of the GNU GPL, and distribute that entire code under the terms of the same version of the GNU GPL. Article 6 - INTELLECTUAL PROPERTY 6.1 OVER THE INITIAL SOFTWARE The Holder owns the economic rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. The Holder undertakes that the Initial Software will remain ruled at least by this Agreement, for the duration set forth in Article 4.2. 6.2 OVER THE CONTRIBUTIONS The Licensee who develops a Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. 6.3 OVER THE EXTERNAL MODULES The Licensee who develops an External Module is the owner of the intellectual property rights over this External Module as defined by applicable law and is free to choose the type of agreement that shall govern its distribution. 6.4 JOINT PROVISIONS The Licensee expressly undertakes: 1. not to remove, or modify, in any manner, the intellectual property notices attached to the Software; 2. to reproduce said notices, in an identical manner, in the copies of the Software modified or not. The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder and/or Contributors on the Software and to take, where applicable, vis-à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder and/or Contributors. Article 7 - RELATED SERVICES 7.1 Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. Only the Licensor offering said maintenance and/or technical assistance services shall incur liability therefor. 7.2 Similarly, any Licensor is entitled to offer to its licensees, under its sole responsibility, a warranty, that shall only be binding upon itself, for the redistribution of the Software and/or the Modified Software, under terms and conditions that it is free to decide. Said warranty, and the financial terms and conditions of its application, shall be subject of a separate instrument executed between the Licensor and the Licensee. Article 8 - LIABILITY 8.1 Subject to the provisions of Article 8.2, the Licensee shall be entitled to claim compensation for any direct loss it may have suffered from the Software as a result of a fault on the part of the relevant Licensor, subject to providing evidence thereof. 8.2 The Licensor's liability is limited to the commitments made under this Agreement and shall not be incurred as a result of in particular: (i) loss due the Licensee's total or partial failure to fulfill its obligations, (ii) direct or consequential loss that is suffered by the Licensee due to the use or performance of the Software, and (iii) more generally, any consequential loss. In particular the Parties expressly agree that any or all pecuniary or business loss (i.e. loss of data, loss of profits, operating loss, loss of customers or orders, opportunity cost, any disturbance to business activities) or any or all legal proceedings instituted against the Licensee by a third party, shall constitute consequential loss and shall not provide entitlement to any or all compensation from the Licensor. Article 9 - WARRANTY 9.1 The Licensee acknowledges that the scientific and technical state-of-the-art when the Software was distributed did not enable all possible uses to be tested and verified, nor for the presence of possible defects to be detected. In this respect, the Licensee's attention has been drawn to the risks associated with loading, using, modifying and/or developing and reproducing the Software which are reserved for experienced users. The Licensee shall be responsible for verifying, by any or all means, the suitability of the product for its requirements, its good working order, and for ensuring that it shall not cause damage to either persons or properties. 9.2 The Licensor hereby represents, in good faith, that it is entitled to grant all the rights over the Software (including in particular the rights set forth in Article 5). 9.3 The Licensee acknowledges that the Software is supplied "as is" by the Licensor without any other express or tacit warranty, other than that provided for in Article 9.2 and, in particular, without any warranty as to its commercial value, its secured, safe, innovative or relevant nature. Specifically, the Licensor does not warrant that the Software is free from any error, that it will operate without interruption, that it will be compatible with the Licensee's own equipment and software configuration, nor that it will meet the Licensee's requirements. 9.4 The Licensor does not either expressly or tacitly warrant that the Software does not infringe any third party intellectual property right relating to a patent, software or any other property right. Therefore, the Licensor disclaims any and all liability towards the Licensee arising out of any or all proceedings for infringement that may be instituted in respect of the use, modification and redistribution of the Software. Nevertheless, should such proceedings be instituted against the Licensee, the Licensor shall provide it with technical and legal assistance for its defense. Such technical and legal assistance shall be decided on a case-by-case basis between the relevant Licensor and the Licensee pursuant to a memorandum of understanding. The Licensor disclaims any and all liability as regards the Licensee's use of the name of the Software. No warranty is given as regards the existence of prior rights over the name of the Software or as regards the existence of a trademark. Article 10 - TERMINATION 10.1 In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. 10.2 A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. Article 11 - MISCELLANEOUS 11.1 EXCUSABLE EVENTS Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. 11.2 Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. 11.3 The Agreement cancels and replaces any or all previous agreements, whether written or oral, between the Parties and having the same purpose, and constitutes the entirety of the agreement between said Parties concerning said purpose. No supplement or modification to the terms and conditions hereof shall be effective as between the Parties unless it is made in writing and signed by their duly authorized representatives. 11.4 In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. 11.5 LANGUAGE The Agreement is drafted in both French and English and both versions are deemed authentic. Article 12 - NEW VERSIONS OF THE AGREEMENT 12.1 Any person is authorized to duplicate and distribute copies of this Agreement. 12.2 So as to ensure coherence, the wording of this Agreement is protected and may only be modified by the authors of the License, who reserve the right to periodically publish updates or new versions of the Agreement, each with a separate number. These subsequent versions may address new issues encountered by Free Software. 12.3 Any Software distributed under a given version of the Agreement may only be subsequently distributed under the same version of the Agreement or a subsequent version, subject to the provisions of Article 5.3.4. Article 13 - GOVERNING LAW AND JURISDICTION 13.1 The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. 13.2 Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Paris Courts having jurisdiction, by the more diligent Party. Version 2.0 dated 2006-09-05. scirenderer-1.1.0/COPYING-FR000066400000000000000000000517331212506735300153730ustar00rootroot00000000000000 CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL Avertissement Ce contrat est une licence de logiciel libre issue d'une concertation entre ses auteurs afin que le respect de deux grands principes préside à sa rédaction: * d'une part, le respect des principes de diffusion des logiciels libres: accès au code source, droits étendus conférés aux utilisateurs, * d'autre part, la désignation d'un droit applicable, le droit français, auquel elle est conforme, tant au regard du droit de la responsabilité civile que du droit de la propriété intellectuelle et de la protection qu'il offre aux auteurs et titulaires des droits patrimoniaux sur un logiciel. Les auteurs de la licence CeCILL (pour Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) sont: Commissariat à l'Energie Atomique - CEA, établissement public de recherche à caractère scientifique, technique et industriel, dont le siège est situé 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris. Centre National de la Recherche Scientifique - CNRS, établissement public à caractère scientifique et technologique, dont le siège est situé 3 rue Michel-Ange, 75794 Paris cedex 16. Institut National de Recherche en Informatique et en Automatique - INRIA, établissement public à caractère scientifique et technologique, dont le siège est situé Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex. Préambule Ce contrat est une licence de logiciel libre dont l'objectif est de conférer aux utilisateurs la liberté de modification et de redistribution du logiciel régi par cette licence dans le cadre d'un modèle de diffusion en logiciel libre. L'exercice de ces libertés est assorti de certains devoirs à la charge des utilisateurs afin de préserver ce statut au cours des redistributions ultérieures. L'accessibilité au code source et les droits de copie, de modification et de redistribution qui en découlent ont pour contrepartie de n'offrir aux utilisateurs qu'une garantie limitée et de ne faire peser sur l'auteur du logiciel, le titulaire des droits patrimoniaux et les concédants successifs qu'une responsabilité restreinte. A cet égard l'attention de l'utilisateur est attirée sur les risques associés au chargement, à l'utilisation, à la modification et/ou au développement et à la reproduction du logiciel par l'utilisateur étant donné sa spécificité de logiciel libre, qui peut le rendre complexe à manipuler et qui le réserve donc à des développeurs ou des professionnels avertis possédant des connaissances informatiques approfondies. Les utilisateurs sont donc invités à charger et tester l'adéquation du logiciel à leurs besoins dans des conditions permettant d'assurer la sécurité de leurs systèmes et/ou de leurs données et, plus généralement, à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. Ce contrat peut être reproduit et diffusé librement, sous réserve de le conserver en l'état, sans ajout ni suppression de clauses. Ce contrat est susceptible de s'appliquer à tout logiciel dont le titulaire des droits patrimoniaux décide de soumettre l'exploitation aux dispositions qu'il contient. Article 1 - DEFINITIONS Dans ce contrat, les termes suivants, lorsqu'ils seront écrits avec une lettre capitale, auront la signification suivante: Contrat: désigne le présent contrat de licence, ses éventuelles versions postérieures et annexes. Logiciel: désigne le logiciel sous sa forme de Code Objet et/ou de Code Source et le cas échéant sa documentation, dans leur état au moment de l'acceptation du Contrat par le Licencié. Logiciel Initial: désigne le Logiciel sous sa forme de Code Source et éventuellement de Code Objet et le cas échéant sa documentation, dans leur état au moment de leur première diffusion sous les termes du Contrat. Logiciel Modifié: désigne le Logiciel modifié par au moins une Contribution. Code Source: désigne l'ensemble des instructions et des lignes de programme du Logiciel et auquel l'accès est nécessaire en vue de modifier le Logiciel. Code Objet: désigne les fichiers binaires issus de la compilation du Code Source. Titulaire: désigne le ou les détenteurs des droits patrimoniaux d'auteur sur le Logiciel Initial. Licencié: désigne le ou les utilisateurs du Logiciel ayant accepté le Contrat. Contributeur: désigne le Licencié auteur d'au moins une Contribution. Concédant: désigne le Titulaire ou toute personne physique ou morale distribuant le Logiciel sous le Contrat. Contribution: désigne l'ensemble des modifications, corrections, traductions, adaptations et/ou nouvelles fonctionnalités intégrées dans le Logiciel par tout Contributeur, ainsi que tout Module Interne. Module: désigne un ensemble de fichiers sources y compris leur documentation qui permet de réaliser des fonctionnalités ou services supplémentaires à ceux fournis par le Logiciel. Module Externe: désigne tout Module, non dérivé du Logiciel, tel que ce Module et le Logiciel s'exécutent dans des espaces d'adressage différents, l'un appelant l'autre au moment de leur exécution. Module Interne: désigne tout Module lié au Logiciel de telle sorte qu'ils s'exécutent dans le même espace d'adressage. GNU GPL: désigne la GNU General Public License dans sa version 2 ou toute version ultérieure, telle que publiée par Free Software Foundation Inc. Parties: désigne collectivement le Licencié et le Concédant. Ces termes s'entendent au singulier comme au pluriel. Article 2 - OBJET Le Contrat a pour objet la concession par le Concédant au Licencié d'une licence non exclusive, cessible et mondiale du Logiciel telle que définie ci-après à l'article 5 pour toute la durée de protection des droits portant sur ce Logiciel. Article 3 - ACCEPTATION 3.1 L'acceptation par le Licencié des termes du Contrat est réputée acquise du fait du premier des faits suivants: * (i) le chargement du Logiciel par tout moyen notamment par téléchargement à partir d'un serveur distant ou par chargement à partir d'un support physique; * (ii) le premier exercice par le Licencié de l'un quelconque des droits concédés par le Contrat. 3.2 Un exemplaire du Contrat, contenant notamment un avertissement relatif aux spécificités du Logiciel, à la restriction de garantie et à la limitation à un usage par des utilisateurs expérimentés a été mis à disposition du Licencié préalablement à son acceptation telle que définie à l'article 3.1 ci dessus et le Licencié reconnaît en avoir pris connaissance. Article 4 - ENTREE EN VIGUEUR ET DUREE 4.1 ENTREE EN VIGUEUR Le Contrat entre en vigueur à la date de son acceptation par le Licencié telle que définie en 3.1. 4.2 DUREE Le Contrat produira ses effets pendant toute la durée légale de protection des droits patrimoniaux portant sur le Logiciel. Article 5 - ETENDUE DES DROITS CONCEDES Le Concédant concède au Licencié, qui accepte, les droits suivants sur le Logiciel pour toutes destinations et pour la durée du Contrat dans les conditions ci-après détaillées. Par ailleurs, si le Concédant détient ou venait à détenir un ou plusieurs brevets d'invention protégeant tout ou partie des fonctionnalités du Logiciel ou de ses composants, il s'engage à ne pas opposer les éventuels droits conférés par ces brevets aux Licenciés successifs qui utiliseraient, exploiteraient ou modifieraient le Logiciel. En cas de cession de ces brevets, le Concédant s'engage à faire reprendre les obligations du présent alinéa aux cessionnaires. 5.1 DROIT D'UTILISATION Le Licencié est autorisé à utiliser le Logiciel, sans restriction quant aux domaines d'application, étant ci-après précisé que cela comporte: 1. la reproduction permanente ou provisoire du Logiciel en tout ou partie par tout moyen et sous toute forme. 2. le chargement, l'affichage, l'exécution, ou le stockage du Logiciel sur tout support. 3. la possibilité d'en observer, d'en étudier, ou d'en tester le fonctionnement afin de déterminer les idées et principes qui sont à la base de n'importe quel élément de ce Logiciel; et ceci, lorsque le Licencié effectue toute opération de chargement, d'affichage, d'exécution, de transmission ou de stockage du Logiciel qu'il est en droit d'effectuer en vertu du Contrat. 5.2 DROIT D'APPORTER DES CONTRIBUTIONS Le droit d'apporter des Contributions comporte le droit de traduire, d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel et le droit de reproduire le logiciel en résultant. Le Licencié est autorisé à apporter toute Contribution au Logiciel sous réserve de mentionner, de façon explicite, son nom en tant qu'auteur de cette Contribution et la date de création de celle-ci. 5.3 DROIT DE DISTRIBUTION Le droit de distribution comporte notamment le droit de diffuser, de transmettre et de communiquer le Logiciel au public sur tout support et par tout moyen ainsi que le droit de mettre sur le marché à titre onéreux ou gratuit, un ou des exemplaires du Logiciel par tout procédé. Le Licencié est autorisé à distribuer des copies du Logiciel, modifié ou non, à des tiers dans les conditions ci-après détaillées. 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION Le Licencié est autorisé à distribuer des copies conformes du Logiciel, sous forme de Code Source ou de Code Objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9, et que, dans le cas où seul le Code Objet du Logiciel est redistribué, le Licencié permette aux futurs Licenciés d'accéder facilement au Code Source complet du Logiciel en indiquant les modalités d'accès, étant entendu que le coût additionnel d'acquisition du Code Source ne devra pas excéder le simple coût de transfert des données. 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE Lorsque le Licencié apporte une Contribution au Logiciel, les conditions de distribution du Logiciel Modifié en résultant sont alors soumises à l'intégralité des dispositions du Contrat. Le Licencié est autorisé à distribuer le Logiciel Modifié, sous forme de code source ou de code objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9, et que, dans le cas où seul le code objet du Logiciel Modifié est redistribué, le Licencié permette aux futurs Licenciés d'accéder facilement au code source complet du Logiciel Modifié en indiquant les modalités d'accès, étant entendu que le coût additionnel d'acquisition du code source ne devra pas excéder le simple coût de transfert des données. 5.3.3 DISTRIBUTION DES MODULES EXTERNES Lorsque le Licencié a développé un Module Externe les conditions du Contrat ne s'appliquent pas à ce Module Externe, qui peut être distribué sous un contrat de licence différent. 5.3.4 COMPATIBILITE AVEC LA LICENCE GNU GPL Le Licencié peut inclure un code soumis aux dispositions d'une des versions de la licence GNU GPL dans le Logiciel modifié ou non et distribuer l'ensemble sous les conditions de la même version de la licence GNU GPL. Le Licencié peut inclure le Logiciel modifié ou non dans un code soumis aux dispositions d'une des versions de la licence GNU GPL et distribuer l'ensemble sous les conditions de la même version de la licence GNU GPL. Article 6 - PROPRIETE INTELLECTUELLE 6.1 SUR LE LOGICIEL INITIAL Le Titulaire est détenteur des droits patrimoniaux sur le Logiciel Initial. Toute utilisation du Logiciel Initial est soumise au respect des conditions dans lesquelles le Titulaire a choisi de diffuser son oeuvre et nul autre n'a la faculté de modifier les conditions de diffusion de ce Logiciel Initial. Le Titulaire s'engage à ce que le Logiciel Initial reste au moins régi par le Contrat et ce, pour la durée visée à l'article 4.2. 6.2 SUR LES CONTRIBUTIONS Le Licencié qui a développé une Contribution est titulaire sur celle-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable. 6.3 SUR LES MODULES EXTERNES Le Licencié qui a développé un Module Externe est titulaire sur celui-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable et reste libre du choix du contrat régissant sa diffusion. 6.4 DISPOSITIONS COMMUNES Le Licencié s'engage expressément: 1. à ne pas supprimer ou modifier de quelque manière que ce soit les mentions de propriété intellectuelle apposées sur le Logiciel; 2. à reproduire à l'identique lesdites mentions de propriété intellectuelle sur les copies du Logiciel modifié ou non. Le Licencié s'engage à ne pas porter atteinte, directement ou indirectement, aux droits de propriété intellectuelle du Titulaire et/ou des Contributeurs sur le Logiciel et à prendre, le cas échéant, à l'égard de son personnel toutes les mesures nécessaires pour assurer le respect des dits droits de propriété intellectuelle du Titulaire et/ou des Contributeurs. Article 7 - SERVICES ASSOCIES 7.1 Le Contrat n'oblige en aucun cas le Concédant à la réalisation de prestations d'assistance technique ou de maintenance du Logiciel. Cependant le Concédant reste libre de proposer ce type de services. Les termes et conditions d'une telle assistance technique et/ou d'une telle maintenance seront alors déterminés dans un acte séparé. Ces actes de maintenance et/ou assistance technique n'engageront que la seule responsabilité du Concédant qui les propose. 7.2 De même, tout Concédant est libre de proposer, sous sa seule responsabilité, à ses licenciés une garantie, qui n'engagera que lui, lors de la redistribution du Logiciel et/ou du Logiciel Modifié et ce, dans les conditions qu'il souhaite. Cette garantie et les modalités financières de son application feront l'objet d'un acte séparé entre le Concédant et le Licencié. Article 8 - RESPONSABILITE 8.1 Sous réserve des dispositions de l'article 8.2, le Licencié a la faculté, sous réserve de prouver la faute du Concédant concerné, de solliciter la réparation du préjudice direct qu'il subirait du fait du Logiciel et dont il apportera la preuve. 8.2 La responsabilité du Concédant est limitée aux engagements pris en application du Contrat et ne saurait être engagée en raison notamment: (i) des dommages dus à l'inexécution, totale ou partielle, de ses obligations par le Licencié, (ii) des dommages directs ou indirects découlant de l'utilisation ou des performances du Logiciel subis par le Licencié et (iii) plus généralement d'un quelconque dommage indirect. En particulier, les Parties conviennent expressément que tout préjudice financier ou commercial (par exemple perte de données, perte de bénéfices, perte d'exploitation, perte de clientèle ou de commandes, manque à gagner, trouble commercial quelconque) ou toute action dirigée contre le Licencié par un tiers, constitue un dommage indirect et n'ouvre pas droit à réparation par le Concédant. Article 9 - GARANTIE 9.1 Le Licencié reconnaît que l'état actuel des connaissances scientifiques et techniques au moment de la mise en circulation du Logiciel ne permet pas d'en tester et d'en vérifier toutes les utilisations ni de détecter l'existence d'éventuels défauts. L'attention du Licencié a été attirée sur ce point sur les risques associés au chargement, à l'utilisation, la modification et/ou au développement et à la reproduction du Logiciel qui sont réservés à des utilisateurs avertis. Il relève de la responsabilité du Licencié de contrôler, par tous moyens, l'adéquation du produit à ses besoins, son bon fonctionnement et de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens. 9.2 Le Concédant déclare de bonne foi être en droit de concéder l'ensemble des droits attachés au Logiciel (comprenant notamment les droits visés à l'article 5). 9.3 Le Licencié reconnaît que le Logiciel est fourni "en l'état" par le Concédant sans autre garantie, expresse ou tacite, que celle prévue à l'article 9.2 et notamment sans aucune garantie sur sa valeur commerciale, son caractère sécurisé, innovant ou pertinent. En particulier, le Concédant ne garantit pas que le Logiciel est exempt d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible avec l'équipement du Licencié et sa configuration logicielle ni qu'il remplira les besoins du Licencié. 9.4 Le Concédant ne garantit pas, de manière expresse ou tacite, que le Logiciel ne porte pas atteinte à un quelconque droit de propriété intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout autre droit de propriété. Ainsi, le Concédant exclut toute garantie au profit du Licencié contre les actions en contrefaçon qui pourraient être diligentées au titre de l'utilisation, de la modification, et de la redistribution du Logiciel. Néanmoins, si de telles actions sont exercées contre le Licencié, le Concédant lui apportera son aide technique et juridique pour sa défense. Cette aide technique et juridique est déterminée au cas par cas entre le Concédant concerné et le Licencié dans le cadre d'un protocole d'accord. Le Concédant dégage toute responsabilité quant à l'utilisation de la dénomination du Logiciel par le Licencié. Aucune garantie n'est apportée quant à l'existence de droits antérieurs sur le nom du Logiciel et sur l'existence d'une marque. Article 10 - RESILIATION 10.1 En cas de manquement par le Licencié aux obligations mises à sa charge par le Contrat, le Concédant pourra résilier de plein droit le Contrat trente (30) jours après notification adressée au Licencié et restée sans effet. 10.2 Le Licencié dont le Contrat est résilié n'est plus autorisé à utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les licences qu'il aura concédées antérieurement à la résiliation du Contrat resteront valides sous réserve qu'elles aient été effectuées en conformité avec le Contrat. Article 11 - DISPOSITIONS DIVERSES 11.1 CAUSE EXTERIEURE Aucune des Parties ne sera responsable d'un retard ou d'une défaillance d'exécution du Contrat qui serait dû à un cas de force majeure, un cas fortuit ou une cause extérieure, telle que, notamment, le mauvais fonctionnement ou les interruptions du réseau électrique ou de télécommunication, la paralysie du réseau liée à une attaque informatique, l'intervention des autorités gouvernementales, les catastrophes naturelles, les dégâts des eaux, les tremblements de terre, le feu, les explosions, les grèves et les conflits sociaux, l'état de guerre... 11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou plusieurs occasions de se prévaloir d'une ou plusieurs dispositions du Contrat, ne pourra en aucun cas impliquer renonciation par la Partie intéressée à s'en prévaloir ultérieurement. 11.3 Le Contrat annule et remplace toute convention antérieure, écrite ou orale, entre les Parties sur le même objet et constitue l'accord entier entre les Parties sur cet objet. Aucune addition ou modification aux termes du Contrat n'aura d'effet à l'égard des Parties à moins d'être faite par écrit et signée par leurs représentants dûment habilités. 11.4 Dans l'hypothèse où une ou plusieurs des dispositions du Contrat s'avèrerait contraire à une loi ou à un texte applicable, existants ou futurs, cette loi ou ce texte prévaudrait, et les Parties feraient les amendements nécessaires pour se conformer à cette loi ou à ce texte. Toutes les autres dispositions resteront en vigueur. De même, la nullité, pour quelque raison que ce soit, d'une des dispositions du Contrat ne saurait entraîner la nullité de l'ensemble du Contrat. 11.5 LANGUE Le Contrat est rédigé en langue française et en langue anglaise, ces deux versions faisant également foi. Article 12 - NOUVELLES VERSIONS DU CONTRAT 12.1 Toute personne est autorisée à copier et distribuer des copies de ce Contrat. 12.2 Afin d'en préserver la cohérence, le texte du Contrat est protégé et ne peut être modifié que par les auteurs de la licence, lesquels se réservent le droit de publier périodiquement des mises à jour ou de nouvelles versions du Contrat, qui posséderont chacune un numéro distinct. Ces versions ultérieures seront susceptibles de prendre en compte de nouvelles problématiques rencontrées par les logiciels libres. 12.3 Tout Logiciel diffusé sous une version donnée du Contrat ne pourra faire l'objet d'une diffusion ultérieure que sous la même version du Contrat ou une version postérieure, sous réserve des dispositions de l'article 5.3.4. Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE 13.1 Le Contrat est régi par la loi française. Les Parties conviennent de tenter de régler à l'amiable les différends ou litiges qui viendraient à se produire par suite ou à l'occasion du Contrat. 13.2 A défaut d'accord amiable dans un délai de deux (2) mois à compter de leur survenance et sauf situation relevant d'une procédure d'urgence, les différends ou litiges seront portés par la Partie la plus diligente devant les Tribunaux compétents de Paris. Version 2.0 du 2006-09-05. scirenderer-1.1.0/README000066400000000000000000000012031212506735300146760ustar00rootroot00000000000000SciRenderer is a rendering library based on JoGL. This Java API allows contructor of 2D or 3D plotting of simple 2d graph to complex scenes. This library has been developped by the Scilab Consortium (DIGITEO) and Scilab Enterprises. This library has been developed in the context of the Collaviz project http://www.collaviz.org/ . Collaviz is a project with the financial support of the French National Research Agency (ANR). This library is released under the CeCILL license. See COPYING-FR or COPYING. Source releases are prepared with: VERSION=1.1.0 git archive master -o scirenderer-$VERSION.tar.gz -9 --prefix scirenderer-$VERSION/ scirenderer-1.1.0/build.xml000066400000000000000000000205551212506735300156520ustar00rootroot00000000000000 Build scirenderer scirenderer-1.1.0/examples/000077500000000000000000000000001212506735300156405ustar00rootroot00000000000000scirenderer-1.1.0/examples/org/000077500000000000000000000000001212506735300164275ustar00rootroot00000000000000scirenderer-1.1.0/examples/org/scilab/000077500000000000000000000000001212506735300176645ustar00rootroot00000000000000scirenderer-1.1.0/examples/org/scilab/forge/000077500000000000000000000000001212506735300207665ustar00rootroot00000000000000scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/000077500000000000000000000000001212506735300232735ustar00rootroot00000000000000scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/000077500000000000000000000000001212506735300251115ustar00rootroot00000000000000scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/ChickenPoxCube.java000066400000000000000000000176711212506735300306220ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.picking.PickingTask; import org.scilab.forge.scirenderer.picking.PickingTools; import org.scilab.forge.scirenderer.renderer.Renderer; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.utils.shapes.geometry.CubeFactory; import java.awt.Dimension; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.nio.FloatBuffer; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class ChickenPoxCube extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Rotating Cube Example"; /** * The last used transformation. */ private Transformation lastTransformation; /** * The clicked point. */ private final ElementsBuffer spritePosition; /** * Private constructor. * This is the main class. */ private ChickenPoxCube() { setTitle(TITLE); /** * Add a {@link MouseUnprojectAdapter} */ MouseListener mua = new MouseUnprojectAdapter(getCanvas()); getPanel().addMouseListener(mua); getCanvas().setMainDrawer(new SimpleCubeDrawer(getCanvas())); spritePosition = getCanvas().getBuffersManager().createElementsBuffer(); animate(true); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new ChickenPoxCube(); } /** * A simple cube drawer. */ private final class SimpleCubeDrawer implements Drawer { /** * The sprite size. */ private static final int SPRITE_RADIUS = 15; /** * The cube geometry. */ private final Geometry cube; /** * A rendering proxy. */ private final Renderer renderer; private final Texture sprite; /** * Default constructor. * @param canvas the canvas where the cube is drawn. */ public SimpleCubeDrawer(Canvas canvas) { cube = CubeFactory.createCube(canvas, 3, true); renderer = canvas.getRendererManager().createRenderer(); final Appearance appearance = new Appearance(); appearance.setLineColor(new Color(0, 0, 0)); appearance.setLineWidth(4); sprite = createSprite(canvas); renderer.setDrawer(new Drawer() { @Override public void draw(DrawingTools dt) { try { dt.draw(cube, appearance); } catch (SciRendererException ignored) { } } @Override public boolean is2DView() { return false; } }); } /** * Sprite creator. * @param canvas the canvas where the sprite will be drawn. * @return a sprite to represent clicked point. */ private Texture createSprite(Canvas canvas) { Texture newSprite = canvas.getTextureManager().createTexture(); newSprite.setDrawer(new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { drawingTools.fillDisc(0, 0, SPRITE_RADIUS, new Color(1, 0, 0)); } @Override public Dimension getTextureSize() { return new Dimension(SPRITE_RADIUS * 2, SPRITE_RADIUS * 2); } @Override public OriginPosition getOriginPosition() { return OriginPosition.CENTER; } }); return newSprite; } @Override public void draw(DrawingTools dt) { try { double t = System.currentTimeMillis() / 50.; dt.clear(new Color()); Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(dt.getCanvas().getDimension(), 1f); Transformation perspective = TransformationFactory.getPerspectiveTransformation(1, 10, 45); Transformation displacement = TransformationFactory.getTranslateTransformation(0, 0, -5); dt.getTransformationManager().getProjectionStack().push(projection.rightTimes(perspective.rightTimes(displacement))); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(t, 1, 2, 3)); lastTransformation = dt.getTransformationManager().getTransformation(); dt.draw(renderer); dt.draw(sprite, AnchorPosition.CENTER, spritePosition); } catch (SciRendererException ignored) { // Should not occur. } } @Override public boolean is2DView() { return false; } } /** * This class is a simple example of picking usage. * @author Pierre Lando */ private final class MouseUnprojectAdapter extends MouseAdapter { private final Canvas canvas; /** * Default constructor. * @param canvas the listened canvas. */ public MouseUnprojectAdapter(Canvas canvas) { this.canvas = canvas; } @Override public void mousePressed(final MouseEvent e) { canvas.getPickingManager().addPickingTask(new PickingTask() { @Override public void perform(PickingTools pickingTools) { Vector3d l = pickingTools.getUnderlyingPoint(e.getPoint()); if ((lastTransformation != null) && (l.getZ() != 1)) { Vector3d lastClickedPoint = lastTransformation.unproject(l); FloatBuffer data = spritePosition.getData(); FloatBuffer newData; if (data == null) { newData = FloatBuffer.allocate(4); newData.rewind(); } else { data.rewind(); newData = FloatBuffer.allocate(data.limit() + 4); float[] dataArray = new float[data.limit()]; data.get(dataArray); newData.put(dataArray); } newData.put(lastClickedPoint.getDataAsFloatArray(4)); spritePosition.setData(newData, 4); } } }); } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/ClippedTetrahedron.java000066400000000000000000000127131212506735300315400ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.clipping.ClippingPlane; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.tranformations.Rotation; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.tranformations.Vector4d; import org.scilab.forge.scirenderer.utils.shapes.geometry.TetrahedronFactory; import javax.swing.BoundedRangeModel; import javax.swing.DefaultBoundedRangeModel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class ClippedTetrahedron extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Clipping Example"; /** * Private constructor. * This is the main class. */ private ClippedTetrahedron() { setTitle(TITLE); BoundedRangeModel brm = new DefaultBoundedRangeModel(0, 0, -100, 100); add(new JSlider(brm), BorderLayout.SOUTH); /** * Add a mouse rotation adapter. */ final MouseRotationAdapter mra = new MouseRotationAdapter( new Rotation(Math.toRadians(90), new Vector3d(1, 0, 0)), getCanvas() ); getPanel().addMouseListener(mra); /** * Set main drawer. */ getCanvas().setMainDrawer(new ClippingDrawer(getCanvas(), mra, brm)); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new ClippedTetrahedron(); } /** * The clipped tetrahedron drawer. * @author Pierre Lando */ private final class ClippingDrawer implements Drawer { private final MouseRotationAdapter mra; private final Geometry tetrahedron; private final BoundedRangeModel brm; /** * Clipping example drawer constructor. * @param canvas the canvas. * @param mra the mouse rotation adapter used for interaction. * @param brm the {@link javax.swing.BoundedRangeModel} used for the clipping plane coordinate. */ public ClippingDrawer(final Canvas canvas, MouseRotationAdapter mra, BoundedRangeModel brm) { this.mra = mra; this.tetrahedron = TetrahedronFactory.createTetrahedron(canvas); this.brm = brm; brm.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { canvas.redraw(); } }); } @Override public void draw(DrawingTools dt) { dt.clear(new Color(1f, 1f, 1f)); try { Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(dt.getCanvas().getDimension(), 1f); dt.getTransformationManager().getProjectionStack().push(projection); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getScaleTransformation(.5, .5, .5)); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(mra.getRotation())); ClippingPlane cp = dt.getClippingManager().getClippingPlane(0); cp.setEnable(true); cp.setEquation(new Vector4d(-1, 0, 0, -getValue())); Appearance appearance = new Appearance(); appearance.setFillColor(new Color(1f, 0f, 0f)); appearance.setLineColor(new Color(.2f, .2f, .2f)); appearance.setLineWidth(3); dt.draw(tetrahedron, appearance); cp.setEquation(new Vector4d(1, 0, 0, getValue())); appearance.setFillColor(new Color(0f, 1f, 0f)); dt.draw(tetrahedron, appearance); cp.setEnable(false); } catch (SciRendererException ignored) { // Should not occur. } } @Override public boolean is2DView() { return false; } /** * Current {@link javax.swing.BoundedRangeModel} value getter. * @return the current {@link javax.swing.BoundedRangeModel}. */ private double getValue() { return -(double) brm.getValue() / 100.0; } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/JLatexMath.java000066400000000000000000000177721212506735300277730ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; import org.scilab.forge.jlatexmath.TeXIcon; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import javax.swing.JComponent; import javax.swing.JTextArea; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; import java.awt.BorderLayout; import java.awt.Dimension; import java.util.EventListener; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class JLatexMath extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "JLatexMath Drawing Example"; /** * Private constructor. * This is the main class. */ private JLatexMath() { setTitle(TITLE); LatexCompositor latexCompositor = new LatexCompositor(); add(latexCompositor, BorderLayout.SOUTH); LatexDrawer latexDrawer = new LatexDrawer(getCanvas()); latexCompositor.addListener(latexDrawer); getCanvas().setMainDrawer(latexDrawer); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new JLatexMath(); } /** * @author Pierre Lando */ private final class LatexCompositor extends JComponent { private static final String GAUSS = "\\int_{-\\infty}^{+\\infty}\\!e^{-x^2}\\, \\mathrm{d}x = \\sqrt \\pi"; private final PlainDocument document; private final JTextArea textArea; /** * Default constructor. */ public LatexCompositor() { setLayout(new BorderLayout()); document = new PlainDocument(); try { document.insertString(0, GAUSS, null); } catch (BadLocationException ignored) { } document.addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { fireDataChanged(); } @Override public void removeUpdate(DocumentEvent e) { fireDataChanged(); } @Override public void changedUpdate(DocumentEvent e) { fireDataChanged(); } }); textArea = new JTextArea(document); add(textArea, BorderLayout.CENTER); } /** * Compute the {@see TeXIcon} corresponding to the current formula. * @return the {@see TeXIcon} corresponding to the current formula. */ public TeXIcon getTextIcon() { try { TeXFormula formula = new TeXFormula(document.getText(0, document.getLength())); return formula.createTeXIcon(TeXConstants.STYLE_DISPLAY, 32); } catch (org.scilab.forge.jlatexmath.ParseException e) { return null; } catch (BadLocationException e) { return null; } } /** * Add a listener on the latex composition. * @param latexDrawer the new listener. */ public void addListener(LatexDrawer latexDrawer) { listenerList.add(LatexCompositorListener.class, latexDrawer); latexDrawer.dataChanged(this); } /** * Notify listeners for a data change. */ private void fireDataChanged() { for (LatexCompositorListener listener : listenerList.getListeners(LatexCompositorListener.class)) { listener.dataChanged(this); } } } /** * @author Pierre Lando */ private interface LatexCompositorListener extends EventListener { /** * Inform listeners from data changes. * @param compositor compositor where data have changed. */ void dataChanged(LatexCompositor compositor); } /** * @author Pierre Lando */ private final class LatexDrawer implements Drawer, LatexCompositorListener { private final Canvas canvas; private Texture sprite; /** * Default constructor. * @param canvas the {@link org.scilab.forge.scirenderer.Canvas} where the drawn will be performed. */ public LatexDrawer(Canvas canvas) { this.canvas = canvas; sprite = null; } @Override public void draw(DrawingTools drawingTools) { drawingTools.clear(new Color()); try { Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(drawingTools.getCanvas().getDimension(), 1f); drawingTools.getTransformationManager().getProjectionStack().push(projection); drawingTools.getTransformationManager().getModelViewStack().push(TransformationFactory.getScaleTransformation(.1, .1, .1)); if (sprite != null) { drawingTools.draw(sprite, AnchorPosition.CENTER, new Vector3d(0, 0, 0)); } } catch (SciRendererException ignored) { // Should not occur. } } @Override public boolean is2DView() { return false; } @Override public void dataChanged(final LatexCompositor compositor) { compositor.textArea.setBackground(Color.RED); final TeXIcon ti = compositor.getTextIcon(); canvas.getTextureManager().dispose(sprite); sprite = null; if (ti != null) { ti.setForeground(java.awt.Color.WHITE); sprite = canvas.getTextureManager().createTexture(); sprite.setDrawer(new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { drawingTools.clear(new Color(0, 0, 0)); drawingTools.draw(ti, -(ti.getIconWidth() / 2), -(ti.getIconHeight() / 2)); } @Override public Dimension getTextureSize() { return new Dimension(ti.getIconWidth(), ti.getIconHeight()); } @Override public TextureDrawer.OriginPosition getOriginPosition() { return TextureDrawer.OriginPosition.CENTER; } }); } /** Wait image to set text area background to green */ new Thread(new Runnable() { @Override public void run() { canvas.waitImage(); compositor.textArea.setBackground(Color.GREEN); } }).start(); canvas.redraw(); } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/JScrollPaneExample.java000066400000000000000000000067351212506735300314570ustar00rootroot00000000000000package org.scilab.forge.scirenderer.examples; import com.jogamp.opengl.util.Animator; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.implementation.jogl.JoGLCanvasFactory; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.utils.shapes.geometry.CubeFactory; import javax.media.opengl.awt.GLCanvas; import javax.media.opengl.awt.GLJPanel; import javax.swing.*; import java.awt.*; /** * @Author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public class JScrollPaneExample extends JFrame { /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new JScrollPaneExample(); } /** The canvas. */ private final Canvas canvas; /** The gl panel. */ private final GLCanvas glPanel; private JScrollPaneExample() { glPanel = new GLCanvas(); canvas = JoGLCanvasFactory.createCanvas(glPanel); glPanel.setPreferredSize(new Dimension(1024, 768)); Animator animator = new Animator(); animator.add(glPanel); animator.start(); final Geometry cube = CubeFactory.createCube(canvas, 5, true); final Appearance appearance = new Appearance(); appearance.setLineWidth(3); appearance.setLineColor(new Color(.7f,.6f,.5f)); canvas.setMainDrawer(new Drawer() { @Override public void draw(DrawingTools drawingTools) { try { double t = System.currentTimeMillis() / 50.; drawingTools.clear(new Color()); Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(drawingTools.getCanvas().getDimension(), 1f); Transformation perspective = TransformationFactory.getPerspectiveTransformation(1, 10, 45); Transformation displacement = TransformationFactory.getTranslateTransformation(0, 0, -5); drawingTools.getTransformationManager().getProjectionStack().push(projection.rightTimes(perspective.rightTimes(displacement))); drawingTools.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(t, 1, 2, 3)); drawingTools.draw(cube, appearance); } catch (SciRendererException ignored) { } } @Override public boolean is2DView() { return false; } }); JPanel panel = new JPanel(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(glPanel); JTextArea textArea = new JTextArea(); textArea.setText("Test\nTest\nTest\nTest\n"); panel.add(scrollPane, BorderLayout.CENTER); panel.add(textArea, BorderLayout.NORTH); add(panel); setLocationRelativeTo(null); setTitle("GLCanvas in JScrollPane example"); setSize(800, 600); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/LightenedCube.java000066400000000000000000000130371212506735300304620ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter; import org.scilab.forge.scirenderer.lightning.Light; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.tranformations.Rotation; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.utils.shapes.geometry.CubeFactory; import java.awt.Dimension; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class LightenedCube extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Lightening Example"; /** * Private constructor. * This is the main class. */ private LightenedCube() { setTitle(TITLE); /** * A MouseRotationAdapter to add some interactivity. */ final MouseRotationAdapter mra = new MouseRotationAdapter( new Rotation(), getCanvas() ); getPanel().addMouseListener(mra); getCanvas().setMainDrawer(new LightenedCubeDrawer(mra, getCanvas())); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new LightenedCube(); } /** * The lightened cube drawer. */ private final class LightenedCubeDrawer implements Drawer { /** * A sprite to represent light position. */ private final Texture sprite; /** * The cube geometry. */ private final Geometry cube; /** * The mouse rotation adapter used for interactivity. */ private final MouseRotationAdapter mra; /** * Default constructor. * @param mouseRotationAdapter the mouse rotation adapter used for interactivity. * @param canvas the canvas where the draw will be performed. */ public LightenedCubeDrawer(MouseRotationAdapter mouseRotationAdapter, Canvas canvas) { sprite = createSprite(canvas); cube = CubeFactory.createCube(canvas, 10); mra = mouseRotationAdapter; } /** * Sprite constructor. * @param canvas the canvas where the sprite is created. * @return the sprite representing the light. */ private Texture createSprite(Canvas canvas) { Texture newSprite = canvas.getTextureManager().createTexture(); newSprite.setDrawer(new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { drawingTools.fillDisc(0, 0, 10, new Color(1, 0, 0)); } @Override public Dimension getTextureSize() { return new Dimension(16, 16); } @Override public OriginPosition getOriginPosition() { return OriginPosition.CENTER; } }); return newSprite; } @Override public void draw(DrawingTools dt) { dt.clear(new Color()); try { Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(dt.getCanvas().getDimension(), 1f); dt.getTransformationManager().getProjectionStack().push(projection); dt.getTransformationManager().getModelViewStack().push(TransformationFactory.getScaleTransformation(.2, .2, .2)); dt.getLightManager().setLightningEnable(true); Light light = dt.getLightManager().getLight(0); light.setEnable(true); light.setAmbientColor(new Color(.5f, .5f, .5f)); light.setDiffuseColor(new Color(.5f, 0, 0)); light.setSpecularColor(new Color(.4f, .4f, 0)); Vector3d lightPosition = new Vector3d(0, 2, -2); light.setPosition(lightPosition); dt.draw(sprite, AnchorPosition.CENTER, lightPosition); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(mra.getRotation())); dt.draw(cube); } catch (SciRendererException ignored) { // Should not occur. } } @Override public boolean is2DView() { return false; } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/LineRendering.java000066400000000000000000000152511212506735300305050ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.DefaultGeometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.TextEntity; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.tranformations.DegenerateMatrixException; import org.scilab.forge.scirenderer.tranformations.Rotation; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.utils.shapes.geometry.TetrahedronFactory; import java.awt.Dimension; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class LineRendering extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Line Rendering Example"; private final LineDrawer drawer; /** * Private constructor. * This is the main class. */ private LineRendering() { setTitle(TITLE); /** * Add a mouse rotation adapter. */ final MouseRotationAdapter mra = new MouseRotationAdapter( new Rotation(Math.toRadians(90), new Vector3d(1, 0, 0)), getCanvas() ); getPanel().addMouseListener(mra); drawer = new LineDrawer(getCanvas(), mra); getCanvas().setMainDrawer(drawer); /** * Add a key listener. */ addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_F) { drawer.switchFace(); getCanvas().redraw(); } } }); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new LineRendering(); } /** * @author Pierre Lando */ private final class LineDrawer implements Drawer { private static final String MESSAGE_TEXT = "Press 'F' to switch culling mode"; private final DefaultGeometry tetrahedron; private final MouseRotationAdapter mra; private final Texture message; /** * Default constructor. * @param canvas the canvas where the drawing will be performed. * @param mouseRotationAdapter the {@link org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter} used for interactivity. */ public LineDrawer(Canvas canvas, MouseRotationAdapter mouseRotationAdapter) { tetrahedron = TetrahedronFactory.createTetrahedron(canvas); tetrahedron.setFaceCullingMode(Geometry.FaceCullingMode.CCW); message = createMessage(canvas); mra = mouseRotationAdapter; } /** * Switch culled face. */ public void switchFace() { switch (tetrahedron.getFaceCullingMode()) { case CCW: tetrahedron.setFaceCullingMode(Geometry.FaceCullingMode.CW); break; default: tetrahedron.setFaceCullingMode(Geometry.FaceCullingMode.CCW); } } @Override public void draw(DrawingTools dt) { dt.clear(new Color(1f, 1f, 1f)); try { Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(dt.getCanvas().getDimension(), 1f); dt.getTransformationManager().getProjectionStack().push(projection); } catch (DegenerateMatrixException ignored) { // Should not occur. } try { dt.draw(message, AnchorPosition.UPPER_LEFT, new Vector3d(-.95, .95, 0)); } catch (SciRendererException ignored) { } try { dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getScaleTransformation(.5, .5, .5)); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(mra.getRotation())); Appearance appearance = new Appearance(); appearance.setLineColor(new Color(.2f, .2f, .2f)); appearance.setLineWidth(3); dt.draw(tetrahedron, appearance); } catch (SciRendererException ignored) { // Should not occur. } } @Override public boolean is2DView() { return false; } /** * Create a help message. * @param canvas the canvas where the message sprite is created. * @return a sprite that draws the message. */ private Texture createMessage(final Canvas canvas) { final TextEntity text = new TextEntity(MESSAGE_TEXT); Texture texture = canvas.getTextureManager().createTexture(); texture.setDrawer(new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { drawingTools.draw(text, 0, 0); } @Override public Dimension getTextureSize() { return text.getSize(); } @Override public OriginPosition getOriginPosition() { return OriginPosition.UPPER_LEFT; } }); return texture; } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/MilkDrop.java000066400000000000000000000261741212506735300275070ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter; import org.scilab.forge.scirenderer.ruler.DefaultRulerModel; import org.scilab.forge.scirenderer.ruler.RulerDrawer; import org.scilab.forge.scirenderer.ruler.RulerModel; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.DefaultGeometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.tranformations.Rotation; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import java.nio.FloatBuffer; import java.nio.IntBuffer; /** * Simple example of SciRenderer usage. * * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class MilkDrop extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "MilkDrop example"; /** * Private constructor. * This is the main class. */ private MilkDrop() { setTitle(TITLE); /** * Add a mouse rotation adapter for interactivity. */ final MouseRotationAdapter mra = new MouseRotationAdapter( new Rotation(Math.toRadians(90), new Vector3d(1, 0, 0)), getCanvas() ); getPanel().addMouseListener(mra); getCanvas().setMainDrawer(new MilkDropDrawer(getCanvas(), mra)); } /** * Main function. * @param arguments main arguments. */ public static void main(String[] arguments) { new MilkDrop(); } /** * @author Pierre Lando */ private final class MilkDropDrawer implements Drawer { private final RulerDrawer rulerDrawer; private final Geometry milkDrop; private final MouseRotationAdapter mouseRotationAdapter; private final Appearance appearance; private DefaultRulerModel xRulerModel; private DefaultRulerModel yRulerModel; private DefaultRulerModel zRulerModel; /** * Default constructor. * @param canvas the canvas where the draw will be done. * @param mra the {@link org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter} used for interactivity. */ public MilkDropDrawer(Canvas canvas, MouseRotationAdapter mra) { this.mouseRotationAdapter = mra; appearance = new Appearance(); appearance.setLineWidth(1); appearance.setLineColor(new Color(0, 0, 0)); rulerDrawer = new RulerDrawer(canvas.getTextureManager()); milkDrop = new MilkDropGeometry(canvas); } @Override public void draw(DrawingTools dt) { dt.clear(new Color(1f, 1f, 1f)); try { Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(dt.getCanvas().getDimension(), 1f); dt.getTransformationManager().getProjectionStack().push(projection); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getScaleTransformation(.03, .03, .03)); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(mouseRotationAdapter.getRotation())); dt.draw(milkDrop, appearance); } catch (SciRendererException ignored) { // Should not occur. } rulerDrawer.draw(dt, getXRulerModel()); rulerDrawer.draw(dt, getYRulerModel()); rulerDrawer.draw(dt, getZRulerModel()); } @Override public boolean is2DView() { return false; } /** * X ruler model getter. * @return the X ruler model. */ public RulerModel getXRulerModel() { if (xRulerModel == null) { xRulerModel = new DefaultRulerModel(); xRulerModel.setFirstPoint(new Vector3d(-20, 20, 0)); xRulerModel.setSecondPoint(new Vector3d(20, 20, 0)); xRulerModel.setValues(-20, 20); xRulerModel.setLineVisible(true); xRulerModel.setTicksDirection(new Vector3d(0, 1, 0)); } return xRulerModel; } /** * Y ruler model getter. * @return the Y ruler model. */ public RulerModel getYRulerModel() { if (yRulerModel == null) { yRulerModel = new DefaultRulerModel(); yRulerModel.setFirstPoint(new Vector3d(20, -20, 0)); yRulerModel.setSecondPoint(new Vector3d(20, 20, 0)); yRulerModel.setValues(-20, 20); yRulerModel.setLineVisible(true); yRulerModel.setTicksDirection(new Vector3d(1, 0, 0)); } return yRulerModel; } /** * Z ruler model getter. * @return the Z ruler model. */ public RulerModel getZRulerModel() { if (zRulerModel == null) { zRulerModel = new DefaultRulerModel(); zRulerModel.setFirstPoint(new Vector3d(20, 20, 20)); zRulerModel.setSecondPoint(new Vector3d(20, 20, -20)); zRulerModel.setValues(-20, 20); zRulerModel.setLineVisible(true); zRulerModel.setTicksDirection(new Vector3d(1, 1, 0)); } return zRulerModel; } } /** * A geometry implementation representing a MilkDrop. * @author Pierre Lando */ private final class MilkDropGeometry extends DefaultGeometry { private static final int HALF_SIDE = 20; private static final int SIDE = 2 * HALF_SIDE + 1; private static final int ELEMENTS_SIZE = 4; /** * @param canvas the canvas where the buffers are created. */ public MilkDropGeometry(Canvas canvas) { FloatBuffer vertices = FloatBuffer.allocate(SIDE * SIDE * ELEMENTS_SIZE); FloatBuffer colors = FloatBuffer.allocate(SIDE * SIDE * ELEMENTS_SIZE); IntBuffer wireIndices = IntBuffer.allocate((SIDE - 1) * (SIDE - 1) * 8); IntBuffer indices = IntBuffer.allocate((SIDE - 1) * (SIDE - 1) * 6); fillVerticesAndColors(vertices, colors); fillIndices(indices, wireIndices); ElementsBuffer vertexBuffer = canvas.getBuffersManager().createElementsBuffer(); ElementsBuffer colorBuffer = canvas.getBuffersManager().createElementsBuffer(); IndicesBuffer indicesBuffer = canvas.getBuffersManager().createIndicesBuffer(); IndicesBuffer wireIndicesBuffer = canvas.getBuffersManager().createIndicesBuffer(); vertexBuffer.setData(vertices, ELEMENTS_SIZE); colorBuffer.setData(colors, ELEMENTS_SIZE); indicesBuffer.setData(indices); wireIndicesBuffer.setData(wireIndices); setFillDrawingMode(FillDrawingMode.TRIANGLES); setLineDrawingMode(LineDrawingMode.SEGMENTS); setPolygonOffsetMode(true); setVertices(vertexBuffer); setColors(colorBuffer); setIndices(indicesBuffer); setWireIndices(wireIndicesBuffer); } /** * Fill indices buffers. * @param indices the triangles indices to fill. * @param wireIndices the segments indices to fill.s */ private void fillIndices(IntBuffer indices, IntBuffer wireIndices) { for (int x = 0; x < SIDE - 1; x++) { for (int y = 0; y < SIDE - 1; y++) { /** * (x, y) -- (x+1, y) * | | * | | * (x, y+1)--(x+1, y+1) * * (x,y) => (x*SIDE + y); * */ if (((x >= 0) && (y < 0)) || ((x < 0) && (y >= 0))) { indices.put((x * SIDE) + y); indices.put(((x + 1) * SIDE) + y); indices.put(((x + 1) * SIDE) + (y + 1)); indices.put((x * SIDE) + y); indices.put(((x + 1) * SIDE) + (y + 1)); indices.put((x * SIDE) + (y + 1)); } else { indices.put((x * SIDE) + y); indices.put(((x + 1) * SIDE) + y); indices.put((x * SIDE) + (y + 1)); indices.put(((x + 1) * SIDE) + y); indices.put(((x + 1) * SIDE) + (y + 1)); indices.put((x * SIDE) + (y + 1)); } wireIndices.put((x * SIDE) + y); wireIndices.put((x * SIDE) + (y + 1)); wireIndices.put((x * SIDE) + (y + 1)); wireIndices.put(((x + 1) * SIDE) + (y + 1)); wireIndices.put(((x + 1) * SIDE) + (y + 1)); wireIndices.put(((x + 1) * SIDE) + y); wireIndices.put(((x + 1) * SIDE) + y); wireIndices.put((x * SIDE) + y); } } } /** * Fill the given buffer with vertices data and color data. * @param vertices the vertices buffer. * @param colors the colors buffer. */ private void fillVerticesAndColors(FloatBuffer vertices, FloatBuffer colors) { vertices.rewind(); colors.rewind(); for (int x = -HALF_SIDE; x <= HALF_SIDE; x++) { for (int y = -HALF_SIDE; y <= HALF_SIDE; y++) { double d = Math.sqrt((x * x) + (y * y)); double z = HALF_SIDE * Math.cos(d) * Math.exp(-d / 6) / 2; vertices.put(x); vertices.put(y); vertices.put((float) z); vertices.put(1); colors.put((float) z); colors.put((float) (1 - z)); colors.put(0); colors.put(1); } } vertices.rewind(); colors.rewind(); } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/RotatableSprite.java000066400000000000000000000326571212506735300310750ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * Copyright (C) 2011 - DIGITEO - Manuel Juliachs * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.TextEntity; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.texture.TextureManager; import org.scilab.forge.scirenderer.tranformations.DegenerateMatrixException; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import java.awt.Dimension; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; /** * A basic example featuring rotatable 2D sprites. * * @author Pierre Lando * @author Manuel Juliachs */ @SuppressWarnings(value = { "serial" }) public final class RotatableSprite extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Rotatable Sprites Example"; /** * Private constructor. * This is the main class. */ private RotatableSprite() { setTitle(TITLE); final RotatableSpriteDrawer drawer = new RotatableSpriteDrawer(getCanvas()); getCanvas().setMainDrawer(drawer); /* Key listener */ getPanel().addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_T) { drawer.toggleAnchorDisplay(); } else if (e.getKeyCode() == KeyEvent.VK_D) { drawer.switchRotationDirection(); } else if (e.getKeyCode() == KeyEvent.VK_M) { drawer.toggleMessageDisplay(); } } }); animate(true); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new RotatableSprite(); } /** * A rotatable sprite drawer. * Draws one rotating sprite for each existing sprite anchor position value. * * @author Manuel Juliachs */ public static class RotatableSpriteDrawer implements Drawer { /** The sprites' text strings. */ private static final String[] TEXT_STRINGS = { "Center anchor", "Left anchor", "Lower-left anchor", "Down anchor", "Lower-right anchor", "Right anchor", "Upper-right anchor", "Up anchor", "Upper-left anchor" }; /** The anchor positions. */ private static final AnchorPosition[] ANCHOR_POSITIONS = { AnchorPosition.CENTER, AnchorPosition.LEFT, AnchorPosition.LOWER_LEFT, AnchorPosition.DOWN, AnchorPosition.LOWER_RIGHT, AnchorPosition.RIGHT, AnchorPosition.UPPER_RIGHT, AnchorPosition.UP, AnchorPosition.UPPER_LEFT }; /** The step added to the rotation angle at each draw call. */ private static final float ROTATION_ANGLE_STEP = 2.5f; /** Arbitrary displacement used to position the sprites. */ private static final float DELTA_POSITION = 0.8f; /** The number of sprites to draw, equal to the number of available sprite anchor position values. */ private static final int NUM_SPRITES = 9; /** The margin used for the text sprites. */ private static final int MARGIN = 4; /** The sprites' coordinates. */ private final float[] positions; /** The buffer used to position anchor sprites. */ private final ElementsBuffer position; /** The text sprites. */ private final Texture[] textSprites; /** The sprite used to draw anchors. */ private final Texture anchorSprite; /** The message sprite. */ private final Texture messageSprite; /** The sprites' text entities. */ private final TextEntity[] textEntities; /** The rotation angle applied to all the sprites. */ private float rotationAngle; /** The line width of the sprites' box. */ private final int lineWidth = 2; /** The line's half width. */ private final int halfLineWidth = lineWidth / 2; /** Specifies whether anchor sprites are displayed or not. */ private boolean anchorsDisplayed; /** Specifies the sprites' rotation direction. */ private boolean clockwiseRotation; /** Specifies whether the message is displayed or not. */ private boolean messageDisplayed; /** * Constructor. * @param canvas the canvas to use. */ public RotatableSpriteDrawer(Canvas canvas) { /* The texture manager. */ TextureManager textureManager = canvas.getTextureManager(); anchorsDisplayed = true; clockwiseRotation = false; messageDisplayed = true; rotationAngle = 0; textEntities = new TextEntity[NUM_SPRITES]; for (int i = 0; i < NUM_SPRITES; i++) { TextEntity textEntity = new TextEntity(TEXT_STRINGS[i]); textEntity.setTextColor(new Color(0.0f, 0.0f, 0.0f)); textEntity.setTextAntiAliased(false); textEntities[i] = textEntity; } textSprites = new Texture[NUM_SPRITES]; for (int i = 0; i < NUM_SPRITES; i++) { textSprites[i] = textureManager.createTexture(); textSprites[i].setDrawer(getTextDrawer(i)); } /* The sprite used to visualize anchor points */ anchorSprite = textureManager.createTexture(); anchorSprite.setDrawer(getSpriteDrawer()); position = canvas.getBuffersManager().createElementsBuffer(); positions = new float[]{ 0, 0, 0, -DELTA_POSITION, 0, 0, -DELTA_POSITION, -DELTA_POSITION, 0, 0, -DELTA_POSITION, 0, DELTA_POSITION, -DELTA_POSITION, 0, DELTA_POSITION, 0, 0, DELTA_POSITION, DELTA_POSITION, 0, 0, DELTA_POSITION, 0, -DELTA_POSITION, DELTA_POSITION, 0 }; position.setData(positions, 3); /* The message sprite */ messageSprite = createMessage(canvas); } @Override public void draw(DrawingTools drawingTools) { try { drawingTools.clear(new Color(1.0f, 1.0f, 1.0f)); Transformation projection = null; try { projection = TransformationFactory.getPreferredAspectRatioTransformation(drawingTools.getCanvas().getDimension(), 1f); } catch (DegenerateMatrixException ignored) { // Should not occur. } drawingTools.getTransformationManager().getProjectionStack().push(projection); for (int i = 0; i < NUM_SPRITES; i++) { drawingTools.draw( textSprites[i], ANCHOR_POSITIONS[i], new Vector3d(positions[3 * i], positions[3 * i + 1], positions[3 * i + 2]), rotationAngle ); } if (anchorsDisplayed) { drawingTools.draw(anchorSprite, AnchorPosition.CENTER, position); } if (messageDisplayed) { drawingTools.draw(messageSprite, AnchorPosition.UPPER_LEFT, new Vector3d(-1.0, 1.0, 0.0)); } if (clockwiseRotation) { rotationAngle -= ROTATION_ANGLE_STEP; } else { rotationAngle += ROTATION_ANGLE_STEP; } rotationAngle %= 360.0f; } catch (SciRendererException ignored) { } } @Override public boolean is2DView() { return false; } /** * Returns the anchor sprite drawer. * @return the anchor sprite drawer. */ public TextureDrawer getSpriteDrawer() { return new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { drawingTools.fillDisc(0, 0, 10, new Color(1, 0, 0)); Appearance appearance = new Appearance(); appearance.setLineColor(new Color(0, 0, 0)); drawingTools.drawCircle(0, 0, 10, appearance); } @Override public Dimension getTextureSize() { return new Dimension(10, 10); } @Override public OriginPosition getOriginPosition() { return OriginPosition.CENTER; } }; } /** * Returns the sprite drawer associated to a particular text sprite. * @param textSpriteIndex the sprite index. * @return the text sprite drawer. */ public TextureDrawer getTextDrawer(final int textSpriteIndex) { if ((textSpriteIndex > (NUM_SPRITES - 1)) || (textSpriteIndex < 0)) { return null; } return new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { TextEntity textEntity = textEntities[textSpriteIndex]; drawingTools.draw(textEntity, 0 + MARGIN + halfLineWidth, 0 + MARGIN + halfLineWidth); Dimension dimension = getTextureSize(); int boxWidth = dimension.width; int boxHeight = dimension.height; Appearance appearance = new Appearance(); appearance.setLineColor(new Color(0, 0, 0)); appearance.setLineWidth((float) lineWidth); drawingTools.drawPolyline(new int[]{halfLineWidth, halfLineWidth, boxWidth - halfLineWidth, halfLineWidth, boxWidth - halfLineWidth, boxHeight - halfLineWidth, halfLineWidth, boxHeight - halfLineWidth, halfLineWidth, halfLineWidth}, appearance); } @Override public Dimension getTextureSize() { Dimension dimension = textEntities[textSpriteIndex].getSize(); int boxWidth = (int) dimension.getWidth() + 2 * MARGIN + lineWidth; int boxHeight = (int) dimension.getHeight() + 2 * MARGIN + lineWidth; return new Dimension(boxWidth, boxHeight); } @Override public OriginPosition getOriginPosition() { return OriginPosition.UPPER_LEFT; } }; } /** * Toggles display of the anchors. */ public void toggleAnchorDisplay() { anchorsDisplayed = !anchorsDisplayed; } /** * Switches the rotation direction. */ public void switchRotationDirection() { clockwiseRotation = !clockwiseRotation; } /** * Toggles display of the help message. */ public void toggleMessageDisplay() { messageDisplayed = !messageDisplayed; } /** * Creates a help message. * @param canvas the canvas where the message sprite is created. * @return a sprite that draws the message. */ private Texture createMessage(Canvas canvas) { final TextEntity text = new TextEntity("Press 'T' to toggle anchor drawing, 'D' to switch the rotation direction, 'M' to toggle this message."); Texture message = canvas.getTextureManager().createTexture(); message.setDrawer(new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { drawingTools.draw(text, 0, 0); } @Override public Dimension getTextureSize() { return text.getSize(); } @Override public OriginPosition getOriginPosition() { return OriginPosition.UPPER_LEFT; } }); return message; } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/ScilabLikePlot2D.java000066400000000000000000000230201212506735300310000ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter; import org.scilab.forge.scirenderer.ruler.DefaultRulerModel; import org.scilab.forge.scirenderer.ruler.RulerDrawer; import org.scilab.forge.scirenderer.ruler.RulerModel; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.DefaultGeometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.tranformations.Rotation; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import java.awt.Dimension; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class ScilabLikePlot2D extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Scilab like 'plot2D' Example"; /** * Private constructor. * This is the main class. */ private ScilabLikePlot2D() { setTitle(TITLE); final MouseRotationAdapter mra = new MouseRotationAdapter( new Rotation(Math.toRadians(0), new Vector3d(1, 0, 0)), getCanvas() ); getPanel().addMouseListener(mra); getCanvas().setMainDrawer(new Plot2DDrawer(getCanvas(), mra)); } /** * Main function. * @param arguments main arguments. */ public static void main(String[] arguments) { new ScilabLikePlot2D(); } /** * A plot2d like drawer * * @author Pierre Lando */ public static class Plot2DDrawer implements Drawer { // Some geometry private final DefaultGeometry plot1; private final DefaultGeometry plot2; // Some sprite and position buffer for it. private final ElementsBuffer plot3Data; private final Texture sprite; // Some rulers. private final RulerDrawer rulerDrawer; private DefaultRulerModel xRulerModel; private DefaultRulerModel yRulerModel; private final MouseRotationAdapter mra; /** * Default constructor. * @param canvas parent {@link org.scilab.forge.scirenderer.Canvas} * @param mra a {@link org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter} to add some interactivity. */ public Plot2DDrawer(Canvas canvas, MouseRotationAdapter mra) { this.mra = mra; /** * Create the ruler drawer. */ rulerDrawer = new RulerDrawer(canvas.getTextureManager()); // Create a geometry ElementsBuffer sinData1 = canvas.getBuffersManager().createElementsBuffer(); sinData1.setData(getSinData(3, 100, 10), 4); plot1 = new DefaultGeometry(); plot1.setFillDrawingMode(Geometry.FillDrawingMode.NONE); plot1.setLineDrawingMode(Geometry.LineDrawingMode.SEGMENTS_STRIP); plot1.setVertices(sinData1); // Create a second geometry ElementsBuffer sinData2 = canvas.getBuffersManager().createElementsBuffer(); sinData2.setData(getSinData(2, 100, 10), 4); plot2 = new DefaultGeometry(); plot2.setFillDrawingMode(Geometry.FillDrawingMode.NONE); plot2.setLineDrawingMode(Geometry.LineDrawingMode.SEGMENTS_STRIP); plot2.setVertices(sinData2); // Create a position buffer to draw some sprite. plot3Data = canvas.getBuffersManager().createElementsBuffer(); plot3Data.setData(getSinData(1, 60, 10), 4); // Create a sprite. sprite = canvas.getTextureManager().createTexture(); sprite.setDrawer(getSpriteDrawer()); } @Override public void draw(DrawingTools drawingTools) { drawingTools.clear(new Color(1f, 1f, 1f)); try { Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(drawingTools.getCanvas().getDimension(), 1f); drawingTools.getTransformationManager().getProjectionStack().push(projection); drawingTools.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getScaleTransformation(.1, .1, .1)); drawingTools.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(mra.getRotation())); Appearance appearance = new Appearance(); // Draw first geometry. appearance.setLineColor(new Color(0, 1, 0)); appearance.setLineWidth(4); drawingTools.draw(plot1, appearance); // Draw second geometry. appearance.setLineColor(new Color(0, 0, 0)); appearance.setLineWidth(1); drawingTools.draw(plot2, appearance); // Draw sprites. drawingTools.draw(sprite, AnchorPosition.CENTER, plot3Data); // Draw rulers. rulerDrawer.draw(drawingTools, getXRulerModel()); rulerDrawer.draw(drawingTools, getYRulerModel()); } catch (SciRendererException ignored) { // Should not occur. } } @Override public boolean is2DView() { return true; } /** * Return a float array filled with some "y = sin(theta * x)" data. * @param theta the data period. * @param density the data density (number of point). * @param bound the data bounds (result have x in [-bound, bound[). * @return a float array filled with some "y = sin(theta * x)" data. */ public float[] getSinData(float theta, int density, float bound) { float[] sinData = new float[density * 4]; for (int i = 0; i < density; i++) { float x = bound * 2 * (i - density / 2f) / density; // x : [-bound, bound[ float y = (float) Math.sin(x * theta); sinData[i * 4] = x; sinData[i * 4 + 1] = y; sinData[i * 4 + 2] = 0; sinData[i * 4 + 3] = 1; } return sinData; } /** * Return a sprite drawer. * @return a sprite drawer. */ public TextureDrawer getSpriteDrawer() { return new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { Appearance appearance = new Appearance(); appearance.setLineColor(new Color(1, 0, 0)); drawingTools.drawPolyline(new int[] { -5, 0, +5, 0 }, appearance); drawingTools.drawPolyline(new int[] { 0, -5, 0, +5 }, appearance); } @Override public Dimension getTextureSize() { return new Dimension(16, 16); } @Override public OriginPosition getOriginPosition() { return OriginPosition.CENTER; } }; } /** * Return the X ruler model. * @return the X ruler model. */ public RulerModel getXRulerModel() { if (xRulerModel == null) { xRulerModel = new DefaultRulerModel(); xRulerModel.setFirstPoint(new Vector3d(-10, -1, 0)); xRulerModel.setSecondPoint(new Vector3d(10, -1, 0)); xRulerModel.setValues(10, -10); xRulerModel.setLineVisible(true); xRulerModel.setTicksDirection(new Vector3d(0, -1, 0)); } return xRulerModel; } /** * Return the Y ruler model. * @return the Y ruler model. */ public RulerModel getYRulerModel() { if (yRulerModel == null) { yRulerModel = new DefaultRulerModel(); yRulerModel.setFirstPoint(new Vector3d(-10, -1, 0)); yRulerModel.setSecondPoint(new Vector3d(-10, 1, 0)); yRulerModel.setValues(1, -1); yRulerModel.setLineVisible(true); yRulerModel.setTicksDirection(new Vector3d(-1, 0, 0)); } return yRulerModel; } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/SimpleRuler.java000066400000000000000000000146051212506735300302250ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.ruler.DefaultRulerModel; import org.scilab.forge.scirenderer.ruler.RulerDrawer; import org.scilab.forge.scirenderer.ruler.RulerModel; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.tranformations.DegenerateMatrixException; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import javax.swing.BoundedRangeModel; import javax.swing.DefaultBoundedRangeModel; import javax.swing.JCheckBox; import javax.swing.JFormattedTextField; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class SimpleRuler extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Ruler Example"; /** * Private constructor. * This is the main class. */ private SimpleRuler() { setTitle(TITLE); final BoundedRangeModel zoomLevel = new DefaultBoundedRangeModel(13, 0, 1, 1000); JPanel buttonsPanel = new JPanel(new FlowLayout()); final JFormattedTextField minValue = new JFormattedTextField(new DecimalFormat("0.0000")); minValue.setValue(1); final JFormattedTextField maxValue = new JFormattedTextField(new DecimalFormat("0.0000")); maxValue.setValue(4); final JCheckBox logBox = new JCheckBox("Log"); logBox.setSelected(true); buttonsPanel.add(minValue); buttonsPanel.add(maxValue); buttonsPanel.add(logBox); buttonsPanel.add(new JSlider(zoomLevel)); add(buttonsPanel, BorderLayout.SOUTH); // SciRenderer canvas. final DefaultRulerModel rulerModel = new DefaultRulerModel(); rulerModel.setFirstPoint(new Vector3d(-1, 0, 0)); rulerModel.setSecondPoint(new Vector3d(1, 0, 0)); rulerModel.setFirstValue(Double.parseDouble(minValue.getValue().toString())); rulerModel.setSecondValue(Double.parseDouble(maxValue.getValue().toString())); rulerModel.setTicksDirection(new Vector3d(0, -1, 0)); rulerModel.setLogarithmic(true); Drawer drawer = new MainRulerDrawer(getCanvas(), zoomLevel, rulerModel); getCanvas().setMainDrawer(drawer); zoomLevel.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { getCanvas().redraw(); } }); logBox.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { if (logBox.isSelected()) { double a = Math.abs(rulerModel.getFirstValue()); double b = Math.abs(rulerModel.getSecondValue()); if (b == 0) { b = 10; } if (a == 0) { a = 1; } rulerModel.setFirstValue(Math.min(a, b)); rulerModel.setSecondValue(Math.max(a, b)); rulerModel.setLogarithmic(true); } else { rulerModel.setLogarithmic(false); } getCanvas().redraw(); } }); ActionListener valueChangedListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { rulerModel.setFirstValue(Double.parseDouble(minValue.getValue().toString())); rulerModel.setSecondValue(Double.parseDouble(maxValue.getValue().toString())); getCanvas().redraw(); } }; maxValue.addActionListener(valueChangedListener); minValue.addActionListener(valueChangedListener); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new SimpleRuler(); } /** * The ruler drawer. */ public static class MainRulerDrawer implements Drawer { private final RulerDrawer rulerDrawer; private final RulerModel rulerModel; private final BoundedRangeModel zoomLevel; /** * Default constructor. * @param canvas the canvas where the draw will be performed. * @param zoomLevel the current zoom level model. * @param rulerModel the current ruler model. */ public MainRulerDrawer(Canvas canvas, BoundedRangeModel zoomLevel, RulerModel rulerModel) { this.zoomLevel = zoomLevel; this.rulerModel = rulerModel; this.rulerDrawer = new RulerDrawer(canvas.getTextureManager()); } @Override public void draw(DrawingTools dt) { dt.clear(new Color(1f, 1f, 1f)); try { Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(dt.getCanvas().getDimension(), 1f); dt.getTransformationManager().getProjectionStack().push(projection); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getScaleTransformation(zoomLevel.getValue() / 100.0)); } catch (DegenerateMatrixException ignored) { // Should not occur. } rulerDrawer.draw(dt, rulerModel); } @Override public boolean is2DView() { return false; } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/Sprites.java000066400000000000000000000142631212506735300274130ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.examples.utils.MouseRotationAdapter; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.tranformations.Rotation; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import java.awt.Dimension; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class Sprites extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Sprites Example"; /** * Private constructor. * This is the main class. */ private Sprites() { setTitle(TITLE); /** * Add a mouse rotation adapter. */ final MouseRotationAdapter mra = new MouseRotationAdapter( new Rotation(Math.toRadians(90), new Vector3d(1, 0, 0)), getCanvas() ); getPanel().addMouseListener(mra); getCanvas().setMainDrawer(new SpritesDrawer(getCanvas(), mra)); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new Sprites(); } /** * Sprites drawer. */ public static class SpritesDrawer implements Drawer { private static final int SPRITE_RADIUS = 5; private final int cubeSize = 8; private final MouseRotationAdapter mouseRotationAdapter; private final ElementsBuffer position; private final Texture sprite; /** * Constructor. * @param canvas the canvas where the sprites are drawn. * @param mra the mouse listener used for the interaction. */ public SpritesDrawer(Canvas canvas, MouseRotationAdapter mra) { mouseRotationAdapter = mra; sprite = createSprite(canvas); position = canvas.getBuffersManager().createElementsBuffer(); position.setData(createData(), 4); } @Override public void draw(DrawingTools drawingTools) { drawingTools.clear(new Color(1, 1, 1)); try { Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(drawingTools.getCanvas().getDimension(), 1f); drawingTools.getTransformationManager().getProjectionStack().push(projection); drawingTools.getTransformationManager().getModelViewStack().push(TransformationFactory.getScaleTransformation(.6, .6, .6)); drawingTools.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(mouseRotationAdapter.getRotation())); drawingTools.draw(sprite, AnchorPosition.CENTER, position); } catch (SciRendererException ignored) { // Should not occur. } } @Override public boolean is2DView() { return false; } /** * Create sprite position data. * @return an array filled with the position where the sprite will be drawn. */ private float[] createData() { float[] data = new float[4 * cubeSize * cubeSize * cubeSize]; int index = 0; for (float i = 0; i < cubeSize; i++) { for (float j = 0; j < cubeSize; j++) { for (float k = 0; k < cubeSize; k++) { data[index++] = (i / (cubeSize - 1)) * 2 - 1; data[index++] = (j / (cubeSize - 1)) * 2 - 1; data[index++] = (k / (cubeSize - 1)) * 2 - 1; data[index++] = 1; } } } return data; } /** * Sprite constructor. * @param canvas the canvas where the sprite will be drawn. * @return the example sprite. */ private Texture createSprite(Canvas canvas) { Texture newSprite = canvas.getTextureManager().createTexture(); newSprite.setDrawer(new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { Appearance appearance = new Appearance(); appearance.setLineColor(new Color(0, 0, 0)); drawingTools.drawPolyline(new int[]{ -SPRITE_RADIUS, 0, +SPRITE_RADIUS, 0, }, appearance); drawingTools.drawPolyline(new int[]{ 0, +SPRITE_RADIUS, 0, -SPRITE_RADIUS }, appearance); } @Override public Dimension getTextureSize() { return new Dimension(SPRITE_RADIUS * 2 + 1, SPRITE_RADIUS * 2 + 1); } @Override public OriginPosition getOriginPosition() { return OriginPosition.CENTER; } }); return newSprite; } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/TextureExample.java000066400000000000000000000360731212506735300307410ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import org.scilab.forge.scirenderer.examples.utils.ExampleFrame; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.DefaultGeometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AbstractTextureDataProvider; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector3d; import java.awt.Dimension; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; import java.util.Date; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class TextureExample extends ExampleFrame { /** * Frame title. */ private static final String TITLE = "Texture Example"; /** * Private constructor. * This is the main class. */ private TextureExample() { setTitle(TITLE); final ClickCounter clickCounter = new ClickCounter(); getPanel().addMouseListener(clickCounter); getCanvas().setMainDrawer(new TextureDrawer(getCanvas(), clickCounter)); animate(true); } /** * Main function. * @param arguments launch arguments. Ignored. */ public static void main(String[] arguments) { new TextureExample(); } /** * Texture drawer. */ private final class TextureDrawer implements Drawer { private final ClickCounter clickCounter; private final Appearance appearance1; private final Appearance appearance2; private final Geometry geometry1; private final Geometry geometry2; /** * Constructor. * @param canvas the canvas where the textures will be drawn. * @param clickCounter the click counter used to determine witch texture is drawn. */ public TextureDrawer(Canvas canvas, ClickCounter clickCounter) { this.clickCounter = clickCounter; geometry1 = new SimpleGeometry(canvas); geometry2 = new LessSimpleGeometry(canvas); Texture texture1 = canvas.getTextureManager().createTexture(); Texture texture2 = canvas.getTextureManager().createTexture(); appearance1 = new Appearance(); texture1.setDataProvider(new Simple2DTextureDataProvider()); appearance1.setTexture(texture1); appearance2 = new Appearance(); texture2.setDataProvider(new Simple1DTextureDataProvider()); appearance2.setTexture(texture2); } @Override public void draw(DrawingTools dt) { dt.clear(new Color()); try { double t = System.currentTimeMillis() / 30.; Transformation projection = TransformationFactory.getPreferredAspectRatioTransformation(dt.getCanvas().getDimension(), 1f); dt.getTransformationManager().getProjectionStack().push(projection); dt.getTransformationManager().getModelViewStack().push(TransformationFactory.getScaleTransformation(Math.sqrt(2) / 2)); dt.getTransformationManager().getModelViewStack().pushRightMultiply(TransformationFactory.getRotationTransformation(t, 1, 2, 3)); if (clickCounter.getCount() % 2 == 0) { dt.draw(geometry1, appearance1); } else { dt.draw(geometry2, appearance2); } } catch (SciRendererException ignored) { // Should not occur. } } @Override public boolean is2DView() { return false; } } /** * This mouse adapter count the number of click. */ private final class ClickCounter extends MouseAdapter { private int count; /** * Default constructor. */ public ClickCounter() { count = 0; } @Override public void mousePressed(MouseEvent e) { count++; } /** * Number of click getter. * @return the number of click until the application start. */ public int getCount() { return count; } } /** * @author Pierre Lando */ private final class SimpleGeometry extends DefaultGeometry implements Geometry { /** * Default constructor. * @param canvas the canvas where the geometry will be created. */ public SimpleGeometry(Canvas canvas) { ElementsBuffer vertices = canvas.getBuffersManager().createElementsBuffer(); vertices.setData(new float[] { -1, -1, 0, 1, -1, +1, 0, 1, +1, +1, 0, 1, +1, -1, 0, 1, }, 4); IndicesBuffer indices = canvas.getBuffersManager().createIndicesBuffer(); indices.setData(new int[] { 0, 1, 2, 0, 2, 3 }); ElementsBuffer textureCoordinates = canvas.getBuffersManager().createElementsBuffer(); textureCoordinates.setData(new float[] { 0, 0, 0, 1, 1, 1, 1, 0 }, 2); setFillDrawingMode(FillDrawingMode.TRIANGLES); setVertices(vertices); setIndices(indices); setTextureCoordinates(textureCoordinates); } } /** * @author Pierre Lando */ private final class LessSimpleGeometry extends DefaultGeometry implements Geometry { private static final int SIZE = 65; private static final double HALF_SIZE = SIZE / 2.; /** * Default constructor. * @param canvas the {@link org.scilab.forge.scirenderer.Canvas} where the drawn will be performed. */ public LessSimpleGeometry(Canvas canvas) { int k; ElementsBuffer vertices = canvas.getBuffersManager().createElementsBuffer(); float[] verticesData = new float [SIZE * SIZE * 4]; k = 0; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { double x = 2 * (i / (SIZE - 1f) - .5); double y = 2 * (j / (SIZE - 1f) - .5); double d = Math.max(Math.abs(x), Math.abs(y)); Vector3d v = new Vector3d(x, y, 0).getNormalized().times(d); verticesData[k++] = (float) v.getX(); verticesData[k++] = (float) v.getY(); verticesData[k++] = 0; verticesData[k++] = 1; } } vertices.setData(verticesData, 4); ElementsBuffer textureCoordinates = canvas.getBuffersManager().createElementsBuffer(); float[] textureCoordinatesData = new float[SIZE * SIZE]; k = 0; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { double v = Math.sqrt(Math.pow(i - HALF_SIZE, 2) + Math.pow(j - HALF_SIZE, 2)); v = (Math.sin(4 * Math.PI * v / SIZE) + 1) / 2; textureCoordinatesData[k++] = (float) v; } } textureCoordinates.setData(textureCoordinatesData, 1); IndicesBuffer indices = canvas.getBuffersManager().createIndicesBuffer(); int[] indicesData = new int [6 * (SIZE - 1) * (SIZE - 1)]; k = 0; int u = 0; for (int i = 0; i < SIZE - 1; i++) { for (int j = 0; j < SIZE - 1; j++) { indicesData[k++] = u; indicesData[k++] = u + 1; indicesData[k++] = u + SIZE + 1; indicesData[k++] = u; indicesData[k++] = u + SIZE + 1; indicesData[k++] = u + SIZE; u++; } u++; } indices.setData(indicesData); setFillDrawingMode(FillDrawingMode.TRIANGLES); setVertices(vertices); setIndices(indices); setTextureCoordinates(textureCoordinates); } } /** * @author Pierre Lando */ private final class Simple1DTextureDataProvider extends AbstractTextureDataProvider { private final int size = 16; private ByteBuffer buffer; /** * Default constructor. */ public Simple1DTextureDataProvider() { this.buffer = ByteBuffer.allocate(4 * size); // 4 for RGBA. buffer.rewind(); new SimpleThread().start(); } /** * Fill the data buffer. */ private void fillBuffer() { double phi = Math.PI * 2 / 1024; long time = new Date().getTime(); long base = (int) ((time / 4) % 1024); ByteBuffer tempBuffer = ByteBuffer.allocate(4 * size); tempBuffer.rewind(); for (int i = 0; i < size; i++) { tempBuffer.put(toByte((Math.sin(base * phi) + 1) / 2)); tempBuffer.put(toByte((Math.sin(2 * base * phi + i) + 1) / 2)); tempBuffer.put(toByte((Math.sin(base * phi + i) + 1) / 2)); tempBuffer.put(toByte(255)); } tempBuffer.rewind(); this.buffer = tempBuffer; } @Override public Dimension getTextureSize() { return new Dimension(size, 1); } @Override public ByteBuffer getData() { buffer.rewind(); return buffer; } @Override public ByteBuffer getSubData(int x, int y, final int width, final int height) { ByteBuffer tempBuffer = ByteBuffer.allocate(4 * width * height); this.buffer.position(x + y * size); byte[] data = new byte[4]; for (int i = x; i < x + width; i++) { for (int j = y; j < y + height; j++) { this.buffer.get(data); tempBuffer.put(data); } } tempBuffer.rewind(); this.buffer.rewind(); return tempBuffer; } @Override public boolean isValid() { return true; } /** * This thread update the texture regularly. */ private class SimpleThread extends Thread { /** * Default constructor. */ public SimpleThread() { } @Override public void run() { for (;;) { fillBuffer(); fireUpdate(); try { synchronized (this) { wait(32); } } catch (InterruptedException e) { break; } } } } } /** * @author Pierre Lando */ private final class Simple2DTextureDataProvider extends AbstractTextureDataProvider { private final int size = 16; private ByteBuffer buffer; /** * Default constructor. */ public Simple2DTextureDataProvider() { this.buffer = ByteBuffer.allocate(4 * size * size); // 4 for RGBA. buffer.rewind(); new SimpleThread().start(); } /** * Fill the data buffer. */ private void fillBuffer() { double phi = Math.PI * 2 / 1024; long time = new Date().getTime(); long base = (int) ((time / 4) % 1024); ByteBuffer tempBuffer = ByteBuffer.allocate(4 * size * size); tempBuffer.rewind(); int k = 0; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { tempBuffer.put(toByte((Math.sin((5 * base + 16 * i) * phi) + 1) / 2)); tempBuffer.put(toByte((Math.sin((2 * base + 8 * j) * phi) + 1) / 2)); tempBuffer.put(toByte((Math.sin((7 * base + 4 * k) * phi) + 1) / 2)); tempBuffer.put(toByte(255)); k++; } } tempBuffer.rewind(); this.buffer = tempBuffer; } @Override public Dimension getTextureSize() { return new Dimension(size, size); } @Override public ByteBuffer getData() { buffer.rewind(); return buffer; } @Override public ByteBuffer getSubData(int x, int y, final int width, final int height) { ByteBuffer tempBuffer = ByteBuffer.allocate(4 * width * height); this.buffer.position(x + y * size); byte[] data = new byte[4]; for (int i = x; i < x + width; i++) { for (int j = y; j < y + height; j++) { this.buffer.get(data); tempBuffer.put(data); } } tempBuffer.rewind(); this.buffer.rewind(); return tempBuffer; } @Override public boolean isValid() { return true; } /** * This thread update the texture regularly. */ private class SimpleThread extends Thread { /** * Default constructor. */ public SimpleThread() { } @Override public void run() { for (;;) { fillBuffer(); fireUpdate(); try { synchronized (this) { wait(32); } } catch (InterruptedException e) { break; } } } } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/utils/000077500000000000000000000000001212506735300262515ustar00rootroot00000000000000scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/utils/ExampleFrame.java000066400000000000000000000045521212506735300314700ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples.utils; import com.jogamp.opengl.util.Animator; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.implementation.jogl.JoGLCanvasFactory; import javax.media.opengl.awt.GLJPanel; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Dimension; /** * @author Pierre Lando */ public abstract class ExampleFrame extends JFrame { /** * The default frame size. */ private static final Dimension DEFAULT_SIZE = new Dimension(800, 800); /** * The used animator. */ private Animator animator; /** * The canvas. */ private final Canvas canvas; /** * The gl panel. */ private final GLJPanel glPanel; /** * Default constructor. * Initialise the GUI. */ protected ExampleFrame() { glPanel = new GLJPanel(); canvas = JoGLCanvasFactory.createCanvas(glPanel); setSize(DEFAULT_SIZE); setLayout(new BorderLayout()); add(glPanel, BorderLayout.CENTER); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } /** * Canvas getter. * @return the {@link Canvas}. */ protected final Canvas getCanvas() { return canvas; } /** * OpenGL panel getter. * @return the OpenGL panel. */ protected final JPanel getPanel() { return glPanel; } /** * Animated scene setter. * @param animated true if the scene is auto-animated. */ protected final void animate(boolean animated) { if (animated && (animator == null)) { animator = new Animator(); animator.add(glPanel); animator.start(); } if (!animated && (animator != null)) { animator.remove(glPanel); animator.stop(); animator = null; } } } scirenderer-1.1.0/examples/org/scilab/forge/scirenderer/examples/utils/MouseRotationAdapter.java000066400000000000000000000060531212506735300332310ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.examples.utils; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.tranformations.Rotation; import org.scilab.forge.scirenderer.tranformations.Vector3d; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; /** * This mouse adapter generate a {@link org.scilab.forge.scirenderer.tranformations.Rotation}, depending on mouse drags. * * @author Pierre Lando */ public class MouseRotationAdapter implements MouseListener, MouseMotionListener { private static final float SPEED_RATIO = 128f; private Rotation currentRotation = new Rotation(Math.toRadians(0), new Vector3d(1, 0, 0)); private Rotation startRotation; private Point startPoint; /** * The canvas will be notified for update. */ private Canvas canvas; /** * Default constructor. * @param startRotation the starting rotation. */ public MouseRotationAdapter(Rotation startRotation) { currentRotation = startRotation; this.canvas = null; } /** * A constructor. * The given canvas will be notified for when the current rotation change. * @param rotation the starting rotation. * @param canvas the canvas to be notified on rotation changes. */ public MouseRotationAdapter(Rotation rotation, Canvas canvas) { currentRotation = rotation; this.canvas = canvas; } @Override public void mousePressed(MouseEvent e) { startRotation = currentRotation; startPoint = e.getPoint(); e.getComponent().addMouseMotionListener(this); } @Override public void mouseReleased(MouseEvent e) { e.getComponent().removeMouseMotionListener(this); } @Override public void mouseDragged(MouseEvent e) { int deltaX = e.getX() - startPoint.x; int deltaY = e.getY() - startPoint.y; Rotation delta = new Rotation(deltaY / SPEED_RATIO, new Vector3d(1, 0, 0)); delta.multiply(new Rotation(deltaX / SPEED_RATIO, new Vector3d(0, 1, 0))); currentRotation = startRotation.times(delta); if (canvas != null) { canvas.redraw(); } } /** * Return the current rotation. * @return the current rotation. */ public Rotation getRotation() { return currentRotation; } @Override public void mouseClicked(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseMoved(MouseEvent e) { } } scirenderer-1.1.0/scirenderer-libs.properties000066400000000000000000000004611212506735300213750ustar00rootroot00000000000000; Define all libs needed by scirenderer ; Uncomment this line and declare path to jogl2.jar gluegen2-rt.jar jlatexmath.jar and native libraries jogl2.jar = /usr/share/java/jogl2.jar gluegen2-rt.jar = /usr/share/java/gluegen2-rt.jar jlatexmath.jar = /usr/share/java/jlatexmath.jar jni.path = /usr/lib/jni scirenderer-1.1.0/scirenderer-version.properties000066400000000000000000000000161212506735300221250ustar00rootroot00000000000000version=1.1.0 scirenderer-1.1.0/src/000077500000000000000000000000001212506735300146115ustar00rootroot00000000000000scirenderer-1.1.0/src/org/000077500000000000000000000000001212506735300154005ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/000077500000000000000000000000001212506735300166355ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/000077500000000000000000000000001212506735300177375ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/000077500000000000000000000000001212506735300222445ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/Canvas.java000066400000000000000000000052561212506735300243320ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer; import org.scilab.forge.scirenderer.buffers.BuffersManager; import org.scilab.forge.scirenderer.picking.PickingManager; import org.scilab.forge.scirenderer.renderer.RendererManager; import org.scilab.forge.scirenderer.texture.TextureManager; import java.awt.Dimension; /** * @author Pierre Lando */ public interface Canvas { /** * Set this canvas main drawer. * @param mainDrawer the new canvas main drawer. */ void setMainDrawer(Drawer mainDrawer); /** * Return the canvas main drawer. * @return the canvas main drawer. */ Drawer getMainDrawer(); /** * Return the renderer manager. * @return the renderer manager. */ RendererManager getRendererManager(); /** * Return the buffers manager of this canvas. * @return the buffers manager of this canvas. */ BuffersManager getBuffersManager(); /** * Return the picking manager. * @return the picking manager. */ PickingManager getPickingManager(); /** * Texture manger getter. * @return the texture manager. */ TextureManager getTextureManager(); /** * Return the canvas width. * @return the canvas width. */ int getWidth(); /** * Return the canvas height. * @return the canvas height. */ int getHeight(); /** * Return the canvas dimension. * @return the canvas dimension. */ Dimension getDimension(); /** * Anti-aliasing level getter. * - 0 for 1x * - 1 for 2x * - 2 for 4x * - 3 for 8x * - 4 for 16x * @return the anti-aliasing level. */ public int getAntiAliasingLevel(); /** * Anti-aliasing level setter. * - 0 for 1x * - 1 for 2x * - 2 for 4x * - 3 for 8x * - 4 for 16x * @param antiAliasingLevel the new level. */ public void setAntiAliasingLevel(int antiAliasingLevel); /** Ask the canvas to perform asynchronous drawing. */ void redraw(); /** Ask the canvas to perform asynchronous drawing. */ void redrawAndWait(); /** Wait until a drawing has been performed */ void waitImage(); /** Destroy canvas : release Semaphore and associated threads */ void destroy(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/Drawer.java000066400000000000000000000014001212506735300243260ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer; /** * @author Pierre Lando */ public interface Drawer { /** * Ask this drawer to draw with the given drawing tools. * @param drawingTools the givens drawing tools. */ void draw(DrawingTools drawingTools); /** * @return true if it is a 2D drawing */ boolean is2DView(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/DrawingTools.java000066400000000000000000000115221212506735300255240ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.clipping.ClippingManager; import org.scilab.forge.scirenderer.lightning.LightManager; import org.scilab.forge.scirenderer.renderer.Renderer; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.tranformations.TransformationManager; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Pierre Lando */ public interface DrawingTools { /** * Return the canvas where draw is done. * @return the canvas where draw is done. */ Canvas getCanvas(); /** * Return the transformation manager. * @return the transformation manager. */ TransformationManager getTransformationManager(); /** * Return the light manager. * @return the light manager. */ LightManager getLightManager(); /** * Return the clipping manager. * @return the clipping manager. */ ClippingManager getClippingManager(); /** * Clear the canvas with the given color. * @param color the color used to clear the canvas. */ void clear(Color color); /** * Clear the canvas with the given color. * @param color the color used to clear the canvas. */ void clear(java.awt.Color color); /** * Clear the depth buffer. */ void clearDepthBuffer(); /** * Ask the given renderer to perform a draw. * @param renderer the given renderer. */ void draw(Renderer renderer); /** * Draw the given geometry with default appearance. * @param geometry the geometry to draw. * @throws SciRendererException if the draw is not possible. */ void draw(Geometry geometry) throws SciRendererException; /** * Draw the given geometry. * @param geometry the geometry to draw. * @param appearance the appearance to use. * @throws SciRendererException if the draw is not possible. */ void draw(Geometry geometry, Appearance appearance) throws SciRendererException; /** * Draw the texture on XY plane in current coordinate. * The texture is drawn on the rectangle [(0,0)-(texture width,texture height)]. * @param texture the texture to drawn. * @throws SciRendererException if the texture is not drawable. */ void draw(Texture texture) throws SciRendererException; /** * Draw the given texture at all given position. * @param texture the texture to draw. * @param anchor the texture anchor position. * @param positions the positions where the texture will be drawn. * @throws SciRendererException if the texture is not drawable. */ void draw(Texture texture, AnchorPosition anchor, ElementsBuffer positions) throws SciRendererException; /** * Draw the given texture at all given position with the given rotation angle. * @param texture the texture to draw. * @param anchor the texture anchor position. * @param positions the positions where the texture will be drawn. * @param rotationAngle the rotation angle. * @throws SciRendererException if the texture is not drawable. */ void draw(Texture texture, AnchorPosition anchor, ElementsBuffer positions, double rotationAngle) throws SciRendererException; /** * Draw the given texture at given position. * @param texture the texture to draw. * @param anchor the texture anchor position. * @param position the position where the texture will be drawn. * @throws SciRendererException if the texture is not drawable. */ void draw(Texture texture, AnchorPosition anchor, Vector3d position) throws SciRendererException; /** * Draw the given texture at given position with the given rotation angle. * @param texture the texture to draw. * @param anchor the texture anchor position. * @param position the position where the texture will be drawn. * @param rotationAngle the rotation angle. * @throws SciRendererException if the texture is not drawable. */ void draw(Texture texture, AnchorPosition anchor, Vector3d position, double rotationAngle) throws SciRendererException; } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/PackageInfo.java000066400000000000000000000014411212506735300252560ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer; /** * This utility class give information about SciRenderer library. * @author Pierre Lando */ public final class PackageInfo { /** * The current version of the library. */ public static final String VERSION = "1.1.0"; /** * Private constructor : this is an utility class. */ private PackageInfo() { } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/SciRendererException.java000066400000000000000000000040471212506735300272000ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer; /** * The SciRendererException is the superclass of all Exception from SciRenderer. * * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public class SciRendererException extends Exception { /** * Constructs a new exception with null as its detail message. */ public SciRendererException() { super(); } /** * Constructs a new exception with the specified detail message. * @param message - the detail message. The detail message is saved for later retrieval by the #Throwable.getMessage() method. */ public SciRendererException(String message) { super(message); } /** * Constructs a new exception with the specified detail message and cause. * @param message - the detail message (which is saved for later retrieval by the Throwable.getMessage() method). * @param cause - the cause (which is saved for later retrieval by the Throwable.getCause() method). (A null value is permitted, and indicates that the cause is nonexistent or unknown.) */ public SciRendererException(String message, Throwable cause) { super(message, cause); } /** * Constructs a new exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause). * @param cause - the cause (which is saved for later retrieval by the Throwable.getCause() method). (A null value is permitted, and indicates that the cause is nonexistent or unknown.) */ public SciRendererException(Throwable cause) { super(cause); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/buffers/000077500000000000000000000000001212506735300237005ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/buffers/BuffersManager.java000066400000000000000000000022301212506735300274270ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.buffers; import java.util.Collection; /** * Interface for a buffers manager. * @author Pierre Lando */ public interface BuffersManager { /** * Create an elements buffer. * @return a new elements buffer. */ ElementsBuffer createElementsBuffer(); /** * Create an indices buffer. * @return a new indices buffer. */ IndicesBuffer createIndicesBuffer(); /** * Release all resources used by the given buffer. * @param buffer the given buffer. */ void dispose(DataBuffer buffer); /** * Release all resources used by the given buffers. * @param buffers the given buffers. */ void dispose(Collection buffers); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/buffers/DataBuffer.java000066400000000000000000000014451212506735300265520ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.buffers; import java.nio.Buffer; /** * Interface for a data buffer. * @author Pierre Lando */ public interface DataBuffer { /** * Return the data. * @return the data. */ Buffer getData(); /** * Return the number of elements. * @return the number of elements. */ int getSize(); void clear(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/buffers/ElementsBuffer.java000066400000000000000000000024541212506735300274560ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.buffers; import java.nio.FloatBuffer; /** * @author Pierre Lando */ public interface ElementsBuffer extends DataBuffer { /** * Set the data. * @param data the new data. * @param elementSize the size of data elements. */ void setData(float[] data, int elementSize); /** * Set the data. * @param data the new data. * @param elementSize the size of data elements. */ void setData(Float[] data, int elementSize); /** * Set the data. * @param data the new data. * @param elementsSize the size of data elements. */ void setData(FloatBuffer data, int elementsSize); @Override FloatBuffer getData(); /** * Return the number of coordinate for one element. * @return the number of coordinate for one element. */ int getElementsSize(); void clear(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/buffers/IndicesBuffer.java000066400000000000000000000017611212506735300272600ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.buffers; import java.nio.IntBuffer; import java.util.Collection; /** * @author Pierre Lando */ public interface IndicesBuffer extends DataBuffer { /** * Set the data * @param indices the new data. */ void setData(int[] indices); /** * Set the data * @param indices the new data. */ void setData(Collection indices); /** * Set the data. * @param indexBuffer the new data. */ void setData(IntBuffer indexBuffer); @Override IntBuffer getData(); void clear(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/clipping/000077500000000000000000000000001212506735300240515ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/clipping/ClippingManager.java000066400000000000000000000021711212506735300277550ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.clipping; /** * Clipping manager interface. * * @author Pierre Lando */ public interface ClippingManager { /** * Return the number of available clipping plane. * At least 6 clipping plane are supported. * @return the number of available clipping plane. */ int getClippingPlaneNumber(); /** * Return the i-th clipping plane. * {@code null} is returned if i is not a valid index. * @param i the given index. * @return the i-th clipping plane. */ ClippingPlane getClippingPlane(int i); /** * Disable all clipping plane. */ void disableClipping(); // TODO add an AABB quick call. (with transformation ?) } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/clipping/ClippingPlane.java000066400000000000000000000032501212506735300274410ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.clipping; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.Vector4d; /** * @author Pierre Lando */ public interface ClippingPlane { /** * Return the status of this clipping plane. * @return the status of this clipping plane. */ boolean isEnable(); /** * Set the status of this clipping plane. * @param isEnable new status of this clipping plane. */ void setEnable(boolean isEnable); /** * Set the clipping plane equation. * @param v the plane coordinate. */ void setEquation(Vector4d v); /** * Return the plane equation. * @return the plane equation. */ Vector4d getEquation(); /** * Set the coordinate transformation for the plane. * @param transformation the new coordinate transformation for the plane. */ void setTransformation(Transformation transformation); /** * Return the coordinate transformation for the plane. * @return the coordinate transformation for the plane. */ Transformation getTransformation(); /** * Return the clipping plane index. * @return the clipping plane index.s */ int getIndex(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/data/000077500000000000000000000000001212506735300231555ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/data/AbstractDataProvider.java000066400000000000000000000037241212506735300300760ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.data; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * @author Pierre Lando * @param The type of data user. */ public abstract class AbstractDataProvider implements DataProvider { private final Set users = Collections.synchronizedSet(new HashSet()); @Override public final void removeDataUser(DataUserType dataUser) { users.remove(dataUser); } @Override public final void addDataUser(DataUserType dataUser) { users.add(dataUser); } /** * Notify all registered data users for a data update. */ protected final void fireUpdate() { for (DataUserType dataUser : users) { dataUser.dataUpdated(); } } /** * Convert given value to a byte. * double in [0, 1] are mapped to [0x00, 0xFF]. * @param value the given value. * @return the byte corresponding to the given value. */ protected byte toByte(double value) { return (byte) (((int) (value * 255)) & 0xFF); } /** * Convert given value to a byte. * double in [0, 1] are mapped to [0x00, 0xFF]. * @param values the given value. * @return the byte corresponding to the given value. */ protected byte[] toByte(float[] values) { byte bytes[] = new byte[values.length]; for (int i = 0; i < values.length; i++) { bytes[i] = toByte(values[i]); } return bytes; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/data/DataProvider.java000066400000000000000000000017501212506735300264070ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.data; /** * @author Pierre Lando * @param The type of data user. */ public interface DataProvider { /** * Remove a data user. * @param dataUser the data user to remove. */ void removeDataUser(DataUserType dataUser); /** * Add a data user. * @param texture the data user to add. */ void addDataUser(DataUserType texture); /** * Data provider validity getter. * @return the validity if this data provider. */ boolean isValid(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/data/DataUser.java000066400000000000000000000011171212506735300255300ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.data; /** * @author Pierre Lando */ public interface DataUser { /** * Notify for data update. */ void dataUpdated(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/000077500000000000000000000000001212506735300252715ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/000077500000000000000000000000001212506735300257455ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/G2DCanvas.java000066400000000000000000000114101212506735300303150ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d; import java.awt.Dimension; import java.awt.Graphics2D; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.implementation.g2d.buffers.G2DBuffersManager; import org.scilab.forge.scirenderer.implementation.g2d.motor.Motor3D; import org.scilab.forge.scirenderer.implementation.g2d.renderer.G2DRendererManager; import org.scilab.forge.scirenderer.implementation.g2d.texture.G2DTextureManager; import org.scilab.forge.scirenderer.picking.PickingManager; import org.scilab.forge.scirenderer.picking.PickingTask; /** * G2D implementation of a Canvas. * * @author Calixte DENIZET */ public final class G2DCanvas implements Canvas { private final G2DDrawingTools drawingTools; private final G2DBuffersManager buffersManager; private final G2DRendererManager rendererManager; private final G2DTextureManager textureManager; private final Motor3D motor; private final Dimension dimension; private boolean drawEnabled = true; /** The anti-aliasing level */ private int antiAliasingLevel = 0; private static final PickingManager PICKINGMANAGER = new PickingManager() { @Override public void addPickingTask(PickingTask pickingTask) { } }; /** * The current mainDrawer. */ private Drawer mainDrawer; /** * Default constructor. * @param autoDrawable the G2D autoDrawable this canvas depend on. */ G2DCanvas(Graphics2D g2d, int width, int height) { this.dimension = new Dimension(width, height); this.motor = new Motor3D(this, g2d, dimension); buffersManager = new G2DBuffersManager(); rendererManager = new G2DRendererManager(); drawingTools = new G2DDrawingTools(this); motor.setClippingPlanes(drawingTools.getClippingManager().getClippingPlanes()); textureManager = new G2DTextureManager(this); } public DrawingTools getDrawingTools() { return drawingTools; } public void setGraphics(Graphics2D g2d, int width, int height) { this.dimension.width = width; this.dimension.height = height; this.motor.setGraphics(g2d); } // Implementation of getter & setter from Canvas. @Override public void setMainDrawer(Drawer mainDrawer) { this.mainDrawer = mainDrawer; } @Override public Drawer getMainDrawer() { return mainDrawer; } @Override public G2DRendererManager getRendererManager() { return rendererManager; } @Override public G2DBuffersManager getBuffersManager() { return buffersManager; } @Override public PickingManager getPickingManager() { return PICKINGMANAGER; } @Override public G2DTextureManager getTextureManager() { return textureManager; } @Override public int getWidth() { return dimension.width; } @Override public int getHeight() { return dimension.height; } @Override public Dimension getDimension() { return dimension; } @Override public int getAntiAliasingLevel() { return antiAliasingLevel; } @Override public void setAntiAliasingLevel(int antiAliasingLevel) { this.antiAliasingLevel = antiAliasingLevel; } @Override public void redraw() { draw(); } @Override public void redrawAndWait() { redraw(); } @Override public void waitImage() { } // G2DCanvas specific getter. public void disableDraw() { drawEnabled = false; } public void enableDraw() { drawEnabled = true; } public void draw() { if (drawEnabled) { try { mainDrawer.draw(drawingTools); getMotor3D().setAntialiased(antiAliasingLevel != 0); getMotor3D().draw(); } catch (Exception e) { System.out.println(e + "::::" + mainDrawer); e.printStackTrace(); } } } /** * Return the OpenGl context. * @return the OpenGl context. */ public Motor3D getMotor3D() { return motor; } @Override public void destroy() { // TODO Auto-generated method stub } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/G2DCanvasFactory.java000066400000000000000000000020451212506735300316510ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d; import java.awt.Graphics2D; import org.scilab.forge.scirenderer.Canvas; /** * @author Pierre Lando */ public final class G2DCanvasFactory { /** * Private constructor. * This is an utility class. */ private G2DCanvasFactory() { } /** * Create a canvas from an auto drawable object. * @param autoDrawable the auto drawable object. * @return a canvas based on the given auto drawable object. */ public static G2DCanvas createCanvas(Graphics2D g2d, int width, int height) { return new G2DCanvas(g2d, width, height); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/G2DDrawingTools.java000066400000000000000000000123061212506735300315230ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.clipping.ClippingManager; import org.scilab.forge.scirenderer.lightning.LightManager; import org.scilab.forge.scirenderer.renderer.Renderer; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.tranformations.TransformationManager; import org.scilab.forge.scirenderer.tranformations.TransformationManagerImpl; import org.scilab.forge.scirenderer.tranformations.TransformationManagerListener; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.implementation.g2d.G2DCanvas; import org.scilab.forge.scirenderer.implementation.g2d.G2DCanvasFactory; import org.scilab.forge.scirenderer.implementation.g2d.clipping.G2DClippingManager; import org.scilab.forge.scirenderer.implementation.g2d.motor.Motor3D; /** * * JoGl implementation of the DrawingTools. * * @author Calixte DENIZET */ public class G2DDrawingTools implements DrawingTools { private final TransformationManager transformationManager; //private final G2DLightManager lightManager; private final G2DClippingManager clippingManager; private final G2DCanvas g2dCanvas; /** * Default constructor. * @param canvas the canvas where this drawing tools live. */ G2DDrawingTools(G2DCanvas canvas) { this.transformationManager = new TransformationManagerImpl(canvas); //this.lightManager = new G2DLightManager(this); this.clippingManager = new G2DClippingManager(this); this.g2dCanvas = canvas; transformationManager.addListener(new TransformationManagerListener() { @Override public void transformationChanged(TransformationManager transformationManager) { if (transformationManager.isUsingSceneCoordinate()) { g2dCanvas.getMotor3D().setTransformation(transformationManager.getG2DProjection(), transformationManager.getG2DSingleProjection()); } else { g2dCanvas.getMotor3D().setTransformation(transformationManager.getG2DWindowProjection(), null); } } }); } public Motor3D getMotor3D() { return g2dCanvas.getMotor3D(); } @Override public G2DCanvas getCanvas() { return g2dCanvas; } @Override public TransformationManager getTransformationManager() { return transformationManager; } @Override public LightManager getLightManager() { return null; //return lightManager; } @Override public G2DClippingManager getClippingManager() { return clippingManager; } @Override public void clear(Color color) { g2dCanvas.getMotor3D().reset(color); } @Override public void clear(java.awt.Color color) { g2dCanvas.getMotor3D().reset(color); } @Override public void clearDepthBuffer() { g2dCanvas.getMotor3D().clearDepth(); } @Override public void draw(Renderer renderer) { g2dCanvas.getRendererManager().draw(this, renderer); } @Override public void draw(Geometry geometry) throws SciRendererException { g2dCanvas.getMotor3D().draw(this, geometry, Appearance.getDefault()); } @Override public void draw(Geometry geometry, Appearance appearance) throws SciRendererException { g2dCanvas.getMotor3D().draw(this, geometry, appearance); } @Override public void draw(Texture texture) throws SciRendererException { g2dCanvas.getTextureManager().draw(this, texture); } @Override public void draw(Texture texture, AnchorPosition anchor, ElementsBuffer positions) { g2dCanvas.getMotor3D().draw(this, texture, anchor, positions, 0); } @Override public void draw(Texture texture, AnchorPosition anchor, ElementsBuffer positions, double rotationAngle) { g2dCanvas.getMotor3D().draw(this, texture, anchor, positions, rotationAngle); } @Override public void draw(Texture texture, AnchorPosition anchor, Vector3d position) { g2dCanvas.getMotor3D().draw(this, texture, anchor, position, 0); } @Override public void draw(Texture texture, AnchorPosition anchor, Vector3d position, double rotationAngle) { g2dCanvas.getMotor3D().draw(this, texture, anchor, position, rotationAngle); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/buffers/000077500000000000000000000000001212506735300274015ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/buffers/G2DBuffersManager.java000066400000000000000000000060331212506735300334320ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.buffers; import org.scilab.forge.scirenderer.buffers.BuffersManager; import org.scilab.forge.scirenderer.buffers.DataBuffer; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import java.util.Collection; import java.util.HashSet; import java.util.Set; /** * @author Pierre Lando */ public final class G2DBuffersManager implements BuffersManager { /** * Set off current buffers. */ private final Set buffers = new HashSet(); // todo : est ce utile d'avoir buffers... pourquoi garder une reference la-dessus // peut etre pr savoir qu'un buffer vient de ce manager et pas d'un autre. /** * Default constructor. */ public G2DBuffersManager() { } @Override public ElementsBuffer createElementsBuffer() { G2DElementsBuffer newBuffer = new G2DElementsBuffer(); buffers.add(newBuffer); return newBuffer; } @Override public IndicesBuffer createIndicesBuffer() { G2DIndicesBuffer newBuffer = new G2DIndicesBuffer(); buffers.add(newBuffer); return newBuffer; } @Override public void dispose(DataBuffer buffer) { DataBuffer localBuffer = getLocalBuffer(buffer); if (localBuffer != null) { localBuffer.clear(); buffers.remove(localBuffer); } } @Override public void dispose(Collection buffers) { for (DataBuffer buffer : buffers) { dispose(buffer); } } /** * This method check buffer to be from here. * @param buffer the given buffer. * @return the G2D instance of the buffer. */ private DataBuffer getLocalBuffer(DataBuffer buffer) { if (buffers.contains(buffer)) { return buffer; } return null; } /** * This method check buffer to be from here. * @param buffer the given buffer. * @return the G2D instance of the buffer. */ private IndicesBuffer getLocalIndicesBuffer(IndicesBuffer buffer) { if (buffer instanceof G2DIndicesBuffer && buffers.contains(buffer)) { return buffer; } return null; } /** * This method check buffer to be from here. * @param buffer the given buffer. * @return the G2D instance of the buffer. */ private ElementsBuffer getLocalElementsBuffer(ElementsBuffer buffer) { if (buffer instanceof G2DElementsBuffer && buffers.contains(buffer)) { return buffer; } return null; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/buffers/G2DElementsBuffer.java000066400000000000000000000137341212506735300334570ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - ScilabEnterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.buffers; import org.scilab.forge.scirenderer.buffers.DataBuffer; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import java.nio.FloatBuffer; /** * @author Calixte DENIZET */ @SuppressWarnings(value = { "serial" }) public class G2DElementsBuffer implements DataBuffer, ElementsBuffer { /** * The current size of one element. */ public static final int ELEMENT_SIZE = 4; /** * The default vertex. */ private static final float[] DEFAULT_VERTEX = new float[] {0, 0, 0, 1}; /** * the data this buffer contain. */ private FloatBuffer data; private final Object mutex; /** * Default constructor. * The constructor is package : only {@link G2DBuffersManager} can instantiate this object. */ G2DElementsBuffer() { mutex = new Object(); data = null; } @Override public void setData(float[] newData, int elementSize) { // Check the given vertex size if ((elementSize < 1) || (elementSize > ELEMENT_SIZE)) { throw new BadElementSizeException(elementSize, 1, ELEMENT_SIZE); } int verticesNumber = newData.length / elementSize; //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber); FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber); buffer.rewind(); // Fill buffer with given data. // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones. int k = 0; for (int i = 0; i < verticesNumber; i++) { for (int j = 0; j < ELEMENT_SIZE; j++) { if (j < elementSize) { buffer.put(newData[k++]); } else { buffer.put(DEFAULT_VERTEX[j]); } } } buffer.rewind(); setData(buffer); } @Override public void setData(Float[] newData, int elementSize) { // Check the given vertex size if ((elementSize < 1) || (elementSize > ELEMENT_SIZE)) { throw new BadElementSizeException(elementSize, 1, ELEMENT_SIZE); } int verticesNumber = newData.length / elementSize; //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber); FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber); buffer.rewind(); // Fill buffer with given data. // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones. int k = 0; for (int i = 0; i < verticesNumber; i++) { for (int j = 0; j < ELEMENT_SIZE; j++) { if (j < elementSize) { buffer.put(newData[k++]); } else { buffer.put(DEFAULT_VERTEX[j]); } } } buffer.rewind(); setData(buffer); } @Override public void setData(FloatBuffer newData, int elementsSize) { // Check the given vertex size if ((elementsSize < 1) || (elementsSize > ELEMENT_SIZE)) { throw new BadElementSizeException(elementsSize, 1, ELEMENT_SIZE); } if (elementsSize == 4) { // No need to complete buffer. if (newData != null) { newData.rewind(); } setData(newData); return; } int verticesNumber = newData.limit() / elementsSize; //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber); FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber); buffer.rewind(); // Fill buffer with given data. // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones. newData.rewind(); for (int i = 0; i < verticesNumber; i++) { for (int j = 0; j < ELEMENT_SIZE; j++) { if (j < elementsSize) { buffer.put(newData.get()); } else { buffer.put(DEFAULT_VERTEX[j]); } } } buffer.rewind(); setData(buffer); } @Override public int getSize() { synchronized (mutex) { if (data == null) { return 0; } else { return data.limit() / ELEMENT_SIZE; } } } @Override public int getElementsSize() { return ELEMENT_SIZE; } @Override public FloatBuffer getData() { synchronized (mutex) { if (data != null) { return data; } else { return null; } } } /** * Really set the data. * @param data the new data. */ private void setData(FloatBuffer data) { synchronized (mutex) { this.data = data; } } /** * A specific runtime exception for bad elements size. */ private static class BadElementSizeException extends RuntimeException { /** * Default constructor. * @param size the size given for elements. * @param min the minimum possible size. * @param max the upper bound of possible size (excluded of possible size). */ public BadElementSizeException(int size, int min, int max) { super("Bad vertex elements size : " + size + ". Should be in [" + min + ", " + (max - 1) + "]"); } } @Override public void clear() { if (data != null) { data.clear(); } data = null; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/buffers/G2DIndicesBuffer.java000066400000000000000000000045131212506735300332540ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.buffers; import org.scilab.forge.scirenderer.buffers.DataBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import java.nio.Buffer; import java.nio.IntBuffer; import java.util.Collection; /** * @author Calixte DENIZET */ public class G2DIndicesBuffer implements IndicesBuffer, DataBuffer { /** * the data this buffer contain. */ private IntBuffer data; /** * Default constructor. * The constructor is package : only {@link G2DBuffersManager} can instantiate this object. */ G2DIndicesBuffer() { data = null; } @Override public void setData(int[] indices) { //IntBuffer buffer = BufferUtil.newIntBuffer(indices.length); IntBuffer buffer = IntBuffer.allocate(indices.length); buffer.rewind(); buffer.put(indices); buffer.rewind(); this.data = buffer; } @Override public void setData(Collection indices) { IntBuffer buffer = IntBuffer.allocate(indices.size()); buffer.rewind(); for (int index : indices) { buffer.put(index); } buffer.rewind(); this.data = buffer; } @Override public void setData(IntBuffer indexBuffer) { //IntBuffer buffer = BufferUtil.newIntBuffer(indexBuffer.limit()); IntBuffer buffer = IntBuffer.allocate(indexBuffer.limit()); buffer.rewind(); indexBuffer.rewind(); buffer.put(indexBuffer); buffer.rewind(); indexBuffer.rewind(); this.data = buffer; } @Override public int getSize() { if (data == null) { return 0; } else { return data.limit(); } } @Override public IntBuffer getData() { return data.asReadOnlyBuffer(); } public void clear() { data.clear(); data = null; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/clipping/000077500000000000000000000000001212506735300275525ustar00rootroot00000000000000G2DClippingManager.java000066400000000000000000000040731212506735300336770ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/clipping/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2011-2012 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.clipping; import java.util.ArrayList; import java.util.List; import org.scilab.forge.scirenderer.clipping.ClippingManager; import org.scilab.forge.scirenderer.clipping.ClippingPlane; import org.scilab.forge.scirenderer.implementation.g2d.G2DDrawingTools; /** * @author Calixte DENIZET */ public class G2DClippingManager implements ClippingManager { /** * Used drawing tools. */ private final G2DDrawingTools drawingTools; /** * Clipping planes array. */ private final List clippingPlanes; /** * Default constructor. * @param drawingTools used drawing tools. */ public G2DClippingManager(G2DDrawingTools drawingTools) { this.drawingTools = drawingTools; this.clippingPlanes = new ArrayList(6); } public List getClippingPlanes() { return clippingPlanes; } @Override public int getClippingPlaneNumber() { return Integer.MAX_VALUE; } @Override public ClippingPlane getClippingPlane(int i) { if (i < 0 || i >= getClippingPlaneNumber()) { return null; } else { if (i >= clippingPlanes.size() || clippingPlanes.get(i) == null) { clippingPlanes.add(i, new G2DClippingPlane(i, drawingTools)); } return clippingPlanes.get(i); } } @Override public void disableClipping() { for (ClippingPlane clippingPlane : clippingPlanes) { if (clippingPlane != null) { clippingPlane.setEnable(false); } } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/clipping/G2DClippingPlane.java000066400000000000000000000065631212506735300334510ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.clipping; import org.scilab.forge.scirenderer.clipping.ClippingPlane; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector4d; import org.scilab.forge.scirenderer.implementation.g2d.G2DDrawingTools; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Pierre Lando */ public class G2DClippingPlane implements ClippingPlane { /** * GL index of this clipping plane. */ private final int index; /** * Clipping plane enabled status. */ private boolean isEnable; private G2DDrawingTools drawingTools; /** * Clipping plane equation look like: {@code x*a + y*b + z*c + d = 0}. * Where {@code equation} is {@code [a, b, c, d]}. */ private Vector4d equation = new Vector4d(0, 0, 0, 0); private Vector4d projectedEquation = new Vector4d(0, 0, 0, 0); private Transformation transformation = TransformationFactory.getIdentity(); private Transformation projectionTransf; private boolean updated; /** * Default constructor. * @param index the id of this clipping plane. */ public G2DClippingPlane(int index, G2DDrawingTools drawingTools) { this.isEnable = false; this.index = index; this.drawingTools = drawingTools; } @Override public boolean isEnable() { return isEnable; } @Override public void setEnable(boolean isEnable) { this.isEnable = isEnable; } @Override public void setEquation(Vector4d v) { Transformation t = drawingTools.getTransformationManager().getModelViewStack().peek(); if (t != null) { equation = getTransformedEquation(v, t); } } @Override public Vector4d getEquation() { Transformation t = drawingTools.getMotor3D().getCurrentSingleTransformation(); if (t != null && projectionTransf != t) { projectionTransf = t; projectedEquation = getTransformedEquation(equation, t); } return projectedEquation; } @Override public void setTransformation(Transformation transformation) { } @Override public Transformation getTransformation() { return transformation; } @Override public int getIndex() { return index; } private static final Vector4d getTransformedEquation(Vector4d equation, Transformation transf) { double[] matrix = transf.getInverseTransformation().getMatrix(); double[] v = equation.getData(); double x = matrix[0] * v[0] + matrix[1] * v[1] + matrix[2] * v[2] + matrix[3] * v[3]; double y = matrix[4] * v[0] + matrix[5] * v[1] + matrix[6] * v[2] + matrix[7] * v[3]; double z = matrix[8] * v[0] + matrix[9] * v[1] + matrix[10] * v[2] + matrix[11] * v[3]; double w = matrix[12] * v[0] + matrix[13] * v[1] + matrix[14] * v[2] + matrix[15] * v[3]; return new Vector4d(x, y, z, w); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/000077500000000000000000000000001212506735300271055ustar00rootroot00000000000000AbstractDrawable3DObject.java000066400000000000000000000252421212506735300344210ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.Path2D; import java.util.HashSet; import java.util.Set; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Calixte DENIZET */ public abstract class AbstractDrawable3DObject { public static final double PRECISION = 1e-8; private static int defaultPrecedence = 0; protected final Vector3d[] vertices; protected final Color[] colors; protected int precedence; protected Boolean is2d; protected Double zindex; protected Vector3d v0; protected Vector3d v1; protected Vector3d v0v1; protected double nv0v1; protected Vector3d normal; protected BoundingBox bbox; protected boolean marked; protected boolean marked2; protected Boolean degenerated; /** * Default constructor * @param vertices the vertices */ public AbstractDrawable3DObject(Vector3d[] vertices, Color[] colors) throws InvalidPolygonException { if (vertices == null || vertices.length == 0) { throw new InvalidPolygonException("Invalid 3D Object: no vertices was givenl"); } this.vertices = vertices; this.colors = colors; if (isDegenerate()) { throw new InvalidPolygonException("Invalid 3D Object: two vertices are the same"); } if (isNanOrInf()) { throw new InvalidPolygonException("Invalid 3D Object: contains NaN or Inf coordinates"); } setPrecedence(defaultPrecedence++); getNormal(); } /** * Get the bounding box * @return the bounding box */ final BoundingBox getBBox() { if (bbox == null) { bbox = BoundingBox.getBoundingBox(this); } return bbox; } /** * Test if an array of colors contains only one color or not * @param colors the colors array * @return true if the array is monochromatic */ public static boolean isMonochromatic(Color[] colors) { if (colors != null && colors.length > 0) { Color c = colors[0]; for (int i = 1; i < colors.length; i++) { if (!c.equals(colors[i])) { return false; } } } return true; } /** * Draw this object on a Graphics2D object * @param g2d the Graphics2d object where to draw */ public abstract void draw(Graphics2D g2d); /** * Reset the default precedence */ public static void resetDefaultPrecedence() { defaultPrecedence = 0; } /** * Set the precedence of this object. * @param precedence the precedence of this object */ public void setPrecedence(int precedence) { this.precedence = precedence; } /** * Get the precedence of this object, i.e. its position in the list of the draw objects. * The first object has a precedence of 0, the second has a precedence of 1, ... * @param the precedence */ public int getPrecedence() { return precedence; } /** * Determinates if this object is 2D in looking at the z coordinates * (when all the drawn objects are 2D, we can avoid the projection) */ public boolean is2D() { if (is2d == null) { for (Vector3d v : vertices) { if (v.getZ() != 0) { is2d = Boolean.FALSE; return is2d; } } is2d = Boolean.TRUE; } return is2d; } /** * Get the normal vector. * If no normal vector has been set then it is calculated in using the cross product of the first two vectors. * @return the normal vector. */ public Vector3d getProvidedNormal() { return normal; } /** * Get the normal vector. * If no normal vector has been set then it is calculated in using the cross product of the first two vectors. * @return the normal vector. */ public Vector3d getNormal() { if (v0v1 == null) { setNormal(); } return v0v1; } /** * Set the normal vector */ protected void setNormal() { v0 = vertices[1].minus(vertices[0]); if (vertices.length >= 3) { v1 = vertices[2].minus(vertices[0]); v0v1 = Vector3d.product(v0, v1); nv0v1 = v0v1.getNorm(); v0v1 = v0v1.times(1 / nv0v1);; } else { v0v1 = new Vector3d(0, 0, 0); } } /** * Determinates if the object is contained into a plane * @return true if the object is planar */ protected boolean isPlanar() { Vector3d n = getNormal(); if (n.isZero() || vertices.length == 3) { return true; } for (int i = 1; i < vertices.length; i++) { if (!isNull(n.scalar(vertices[0].minus(vertices[i])))) { return false; } } return true; } public int isBehind(Vector3d v, double a) { double[] mM = minmax3D(this, v); if (isPositiveOrNull(mM[0] + a)) { return 1; } if (mM[1] + a < 0) { return -1; } return 0; } public static boolean isBehind(Vector3d M, Vector3d v, double a) { return isPositiveOrNull(M.scalar(v) + a); } /** * Get the projected polyline of this object * @return a path 2D */ protected Path2D getProjectedPolyLine() { Path2D.Double path = new Path2D.Double(); path.moveTo(vertices[0].getX(), vertices[0].getY()); for (int i = 1; i < vertices.length; i++) { path.lineTo(vertices[i].getX(), vertices[i].getY()); } return path; } /** * Get the projected contour (i.e. a closed polyline) of this object * @return a path 2D */ protected Path2D getProjectedContour() { Path2D path = getProjectedPolyLine(); path.closePath(); return path; } /** * @param d a number * @return true if d is near zero */ protected final static boolean isNull(final double d) { return Math.abs(d) <= PRECISION; } /** * @param d a number * @return true if d is greater than zero */ protected final static boolean isPositiveOrNull(final double d) { return d >= 0 || isNull(d); } /** * @param d a number * @return true if d is greater than zero */ protected final static boolean isNegativeOrNull(final double d) { return d <= 0 || isNull(d); } /** * @param d1 a number * @param d2 a number * @return true if d1 is greater than d2 */ protected final static boolean isGreaterOrEqual(final double d1, final double d2) { return isPositiveOrNull(d1 - d2); } /** * @param d1 a number * @param d2 a number * @return true if d1 is lower than d2 */ protected final static boolean isLowerOrEqual(final double d1, final double d2) { return isPositiveOrNull(d2 - d1); } /** * @param d1 a number * @param d2 a number * @return true if d1 is equal to d2 */ protected final static boolean isEqual(final double d1, final double d2) { return isNull(d1 - d2); } /** * Get min-max of the projections of the vertices of o on v * @param o an object * @param v a vector * @return an array of size 2 containing min-max. */ protected static final double[] minmax3D(final AbstractDrawable3DObject o, final Vector3d v) { double min = v.scalar(o.vertices[0]); double max = min; for (int i = 1; i < o.vertices.length; i++) { double s = v.scalar(o.vertices[i]); if (s < min) { min = s; } else if (s > max) { max = s; } } return new double[]{min, max}; } /** * Get min-max of the projections of the vertices of o on v * @param o an object * @param v a vector * @return an array of size 2 containing min-max. */ protected static final double[] minmax2D(final AbstractDrawable3DObject o, final double x, final double y) { double min = x * o.vertices[0].getX() + y * o.vertices[0].getY(); double max = min; for (int i = 1; i < o.vertices.length; i++) { double s = x * o.vertices[i].getX() + y * o.vertices[i].getY(); if (s < min) { min = s; } else if (s > max) { max = s; } } return new double[]{min, max}; } protected static final Color getColorsBarycenter(final Color c1, final Color c2, final double w1, final double w2) { if (c1 != null && c2 != null && !c1.equals(c2)) { float[] comp1 = c1.getComponents(null); float[] comp2 = c2.getComponents(null); return new Color((float) (comp1[0] * w1 + comp2[0] * w2), (float) (comp1[1] * w1 + comp2[1] * w2), (float) (comp1[2] * w1 + comp2[2] * w2), (float) (comp1[3] * w1 + comp2[3] * w2)); } return c1; } /** * @return true if there are two vertices which are indentical */ protected boolean isDegenerate() { if (degenerated == null) { Set set = new HashSet(); for (Vector3d v : vertices) { set.add(v); } degenerated = set.size() != vertices.length; } return degenerated; } protected boolean isNanOrInf() { for (Vector3d v : vertices) { if (isNanOrInf(v)) { return true; } } return false; } public static final boolean isNanOrInf(final Vector3d v) { final double x = v.getX(); if (Double.isNaN(x) || Double.isInfinite(x)) { return true; } final double y = v.getY(); if (Double.isNaN(y) || Double.isInfinite(y)) { return true; } final double z = v.getZ(); if (Double.isNaN(z) || Double.isInfinite(z)) { return true; } return false; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/BoundingBox.java000066400000000000000000000112421212506735300321660ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Calixte DENIZET * * Bounding box of a 3D object, useful to speed-up intersection detection. */ public class BoundingBox { private double minX = Double.POSITIVE_INFINITY; private double maxX = Double.NEGATIVE_INFINITY; private double minY = Double.POSITIVE_INFINITY; private double maxY = Double.NEGATIVE_INFINITY; private double minZ = Double.POSITIVE_INFINITY; private double maxZ = Double.NEGATIVE_INFINITY; /** * Default constructor * @param minX the minimal X * @param maxX the maximal X * @param minY the minimal Y * @param maxY the maximal Y * @param minZ the minimal Z * @param maxZ the maximal Z */ public BoundingBox(double minX, double maxX, double minY, double maxY, double minZ, double maxZ) { this.minX = minX; this.maxX = maxX; this.minY = minY; this.maxY = maxY; this.minZ = minZ; this.maxZ = maxZ; } /** * Get the relative x-position of this bounding-box and of the box * @param box a BoundingBox * @return 1 if box is on the right, -1 if on the left and 0 if nothing. */ public int xCompare(BoundingBox box) { if (box.minX >= maxX) { return -1; } if (minX >= box.maxX) { return 1; } return 0; } /** * Get the relative y-position of this bounding-box and of the box * @param box a BoundingBox * @return 1 if box is on the bottom, -1 if on the top and 0 if nothing. */ public int yCompare(BoundingBox box) { if (box.minY >= maxY) { return -1; } if (minY >= box.maxY) { return 1; } return 0; } /** * Get the relative z-position of this bounding-box and of the box * @param box a BoundingBox * @return 1 if box is on the front, -1 if behind and 0 if nothing. */ public int zCompare(BoundingBox box) { if (box.minZ >= maxZ) { return 1; } if (minZ >= box.maxZ) { return -1; } return 0; } /** * @param box a BoundingBox * @return true if this BoundingBox and the box have an intersection */ public boolean isIntersecting(BoundingBox box) { return box.maxX >= minX && maxX >= box.minX && box.maxY >= minY && maxY >= box.minY && box.maxZ >= minZ && maxZ >= box.minZ; } /** * @param box a BoundingBox * @return true if this BoundingBox and the box have a strict intersection */ public boolean isStrictlyIntersecting(BoundingBox box) { return box.maxX > minX && maxX > box.minX && box.maxY > minY && maxY > box.minY && box.maxZ > minZ && maxZ > box.minZ; } /** * Get the bounding box of an object * @param object a 3D object * @return the corresponding bounding-box */ public static BoundingBox getBoundingBox(AbstractDrawable3DObject object) { Vector3d[] vertices = object.vertices; double minX = Double.POSITIVE_INFINITY; double maxX = Double.NEGATIVE_INFINITY; double minY = Double.POSITIVE_INFINITY; double maxY = Double.NEGATIVE_INFINITY; double minZ = Double.POSITIVE_INFINITY; double maxZ = Double.NEGATIVE_INFINITY; for (int i = 0; i < vertices.length; i++) { double x = vertices[i].getX(); double y = vertices[i].getY(); double z = vertices[i].getZ(); if (x < minX) { minX = x; } if (x > maxX) { maxX = x; } if (y < minY) { minY = y; } if (y > maxY) { maxY = y; } if (z < minZ) { minZ = z; } if (z > maxZ) { maxZ = z; } } return new BoundingBox(minX, maxX, minY, maxY, minZ, maxZ); } @Override public String toString() { return "[" + minX + ";" + maxX + "]x" + "[" + minY + ";" + maxY + "]x" + "[" + minZ + ";" + maxZ + "]"; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/ConvexObject.java000066400000000000000000000252451212506735300323510ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Shape; import java.util.ArrayList; import java.util.List; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.tranformations.Vector4d; /** * @author Calixte DENIZET * * Class to represent a convex object. * Collision and relative positions of convexs object are relatively easy to determinate. * About the method isBehind, it could be interesting to use the algorithm of Chung-Wang. */ public abstract class ConvexObject extends AbstractDrawable3DObject { private List areas; /** * Default constructor * @param vertices the vertices * @param colors the colors */ public ConvexObject(Vector3d[] vertices, Color[] colors) throws InvalidPolygonException { super(vertices, colors); } /** * Abstract method * Break this ConvexObject against the ConvexObject o * @param o a ConvexObject * @return a list of ConvexObject. */ public abstract List breakObject(ConvexObject o); /** * Abstract method * Break this ConvexObject against a plane * @param v plane definition * @return a list of ConvexObject. */ public abstract List breakObject(Vector4d v); public void addArea(ConvexObject co) { if (areas == null) { areas = new ArrayList(); } areas.add(co); } protected void drawAreas(Graphics2D g2d) { if (areas != null) { for (ConvexObject co : areas) { Shape oldClip = g2d.getClip(); g2d.clip(this.getProjectedContour()); co.draw(g2d); g2d.setClip(oldClip); } } } /** * Test the coplanarity of two objects * @param o a ConvexObject * @return true if the two objects are coplanar */ public boolean areCoplanar(ConvexObject o) { if (!(this instanceof Segment)) { double sc = vertices[0].scalar(v0v1); if (o instanceof Segment) { return isEqual(sc, o.vertices[0].scalar(v0v1)) && isEqual(sc, o.vertices[1].scalar(v0v1)); } return isEqual(sc, o.vertices[0].scalar(v0v1)) && isEqual(sc, o.vertices[1].scalar(v0v1)) && isEqual(sc, o.vertices[2].scalar(v0v1)); } if (!(o instanceof Segment)) { return o.areCoplanar(this); } if (o.vertices[0].equals(vertices[0]) || o.vertices[1].equals(vertices[0]) || o.vertices[0].equals(vertices[1]) || o.vertices[1].equals(vertices[1])) { return true; } Vector3d v = Vector3d.product(v0, o.v0); return isNull(v.scalar(vertices[0].minus(o.vertices[0]))); } /** * Check if o is behind this. * Take care: the algorithms used are for convex objects (typically tri-tri, seg-seg or tri-seg) * @return true if o is behind this */ public int isBehind(ConvexObject o) { BoundingBox bbox = getBBox(); BoundingBox obbox = o.getBBox(); // Quick test in using bounding boxes if (!bbox.isIntersecting(obbox)) { if (bbox.xCompare(obbox) != 0 || bbox.yCompare(obbox) != 0) { return 0; } } // Check if the two objects intersect in projection plane or not if (check2DIntersection(o)) { // We have a strict intersection or an intersection on an edge if (areCoplanar(o)) { return getPrecedence() > o.getPrecedence() ? 1 : -1; } // Quick test with bounding-box along z-axis int ret = bbox.zCompare(obbox); if (ret != 0) { return ret; } // In the most of the cases, one of the two following test are sufficient to determinate // if one object is behind or on front of the plane containing this or o ret = check(o, getNormal()); if (ret != 0) { return ret; } ret = check(o, o.getNormal()); if (ret != 0) { return ret; } // Check against the cross product of one edge of this and one edge of o int M = vertices.length == 2 ? 1 : vertices.length; int N = o.vertices.length == 2 ? 1 : o.vertices.length; for (int j = 0; j < M; j++) { int l = (j + 1 < vertices.length) ? j + 1 : 0; Vector3d e = vertices[l].minus(vertices[j]); for (int k = 0; k < N; k++) { int m = (k + 1 < o.vertices.length) ? k + 1 : 0; Vector3d oe = o.vertices[m].minus(o.vertices[k]); ret = check(o, Vector3d.product(e, oe).getNormalized()); if (ret != 0) { return ret; } } } // At this point: there is a collision between the two objects return 2; } else { return 0; } } /** * Check the intersections of the projection on the xOy-plane of this and o * The algorithm is the following: for each edge, determinate the normal vector and project all the points * of this and o on the normal. If the intersection of [this.min,this.max] and [o.min, o.max] is empty, then * we have a separating line so the two objects are separated. * @param o the object to test with this * @return true if there is a collision */ public boolean check2DIntersection(final ConvexObject o) { int ret = check2D(this, o); if (ret != -1) { return false; } ret = check2D(o, this); if (ret != -1) { return false; } return true; } /** * Check the intersections of the projection on the xOy-plane of this and o * The algorithm is the following: for each edge, determinate the normal vector and project all the points * of this and o on the normal. If the intersection of [this.min,this.max] and [o.min, o.max] is empty, then * we have a separating line so the two objects are separated. * @param o the object to test with this * @return true if there is a collision */ public boolean check2DTrueIntersection(final ConvexObject o) { int ret = check2D2(this, o); if (ret == 1) { return true; } else if (ret == 0) { return false; } ret = check2D2(o, this); if (ret == 1) { return true; } else if (ret == 0) { return false; } return true; } /** * Check 2D intersection of two convex objects * @param o1 first object * @param o2 second object * @return -1 if strict intersection, 1 if intersection on an edge and 0 if no intersection */ private static final int check2D(final ConvexObject o1, final ConvexObject o2) { // When o1 is a Segment (i.e. o1.vertices;length == 2) it is mandatory to check against ortho(v1-v0) and ortho(v0-v1) int M = o1.vertices.length == 2 ? 1 : o1.vertices.length; for (int i = 0; i < M; i++) { int j = (i + 1 < o1.vertices.length) ? i + 1 : 0; double xN = o1.vertices[i].getY() - o1.vertices[j].getY(); double yN = o1.vertices[j].getX() - o1.vertices[i].getX(); double n = Math.hypot(xN, yN); xN /= n; yN /= n; double[] mM = minmax2D(o1, xN, yN); double min = mM[0]; double max = mM[1]; mM = minmax2D(o2, xN, yN); double omin = mM[0]; double omax = mM[1]; if (max < omin || omax < min) { return 0; } if (isEqual(max, omin) || isEqual(omax, min)) { return 1; } } return -1; } /** * Check 2D intersection of two convex objects * @param o1 first object * @param o2 second object * @return -1 if strict intersection, 1 if intersection on an edge and 0 if no intersection */ private static final int check2D2(final ConvexObject o1, final ConvexObject o2) { // When o1 is a Segment (i.e. o1.vertices;length == 2) it is mandatory to check against ortho(v1-v0) and ortho(v0-v1) int M = o1.vertices.length == 2 ? 1 : o1.vertices.length; boolean bool = false; for (int i = 0; i < M; i++) { int j = (i + 1 < o1.vertices.length) ? i + 1 : 0; double xN = o1.vertices[i].getY() - o1.vertices[j].getY(); double yN = o1.vertices[j].getX() - o1.vertices[i].getX(); double n = Math.hypot(xN, yN); xN /= n; yN /= n; double[] mM = minmax2D(o1, xN, yN); double min = mM[0]; double max = mM[1]; mM = minmax2D(o2, xN, yN); double omin = mM[0]; double omax = mM[1]; if (max < omin || omax < min) { return 0; } if (!bool && (isEqual(max, omin) || isEqual(omax, min))) { bool = true; } } if (bool) { return 1; } return -1; } /** * Check the intersection this and o against vector v. * The algorithm is just to project this and o on the vector v and to check if the two projected sets * can be separated. * @param v the vector where to project * @return 1 if o is behind this, 0 if it is undeterminated and -1 if this is behind o. */ protected int check(final ConvexObject o, final Vector3d v) { if (!v.isNearZero()) { double[] mM = minmax3D(this, v); double min = mM[0]; double max = mM[1]; mM = minmax3D(o, v); double omin = mM[0]; double omax = mM[1]; double z = v.getZ(); if (Math.signum(z) == 0) { return 0; } if (isLowerOrEqual(max, omin)) { return (int) Math.signum(z); } if (isLowerOrEqual(omax, min)) { return (int) -Math.signum(z); } } return 0; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/DrawTools.java000066400000000000000000000332461212506735300316760ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.BasicStroke; import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics2D; import java.awt.LinearGradientPaint; import java.awt.Paint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.util.Arrays; import java.awt.geom.Point2D; import java.awt.MultipleGradientPaint; /** * @author Calixte DENIZET */ public final class DrawTools { private static final Stroke stroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); private static final Stroke EMPTYSTROKE = new BasicStroke(0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); private static final Color TRANSLUCENT_BLACK = new Color(0, 0, 0, 0); /** * Fill a triangle in using a Gouraud shading * Only two gradient are used rather than three. * @param g2d the Graphics2D where to draw * @param t the Triangle to fill */ public static final void fillGouraud(final Graphics2D g2d, final Triangle t) { Path2D contour = t.getProjectedContour(); double[] v0 = new double[]{t.vertices[0].getX(), t.vertices[0].getY()}; double[] v1 = new double[]{t.vertices[1].getX(), t.vertices[1].getY()}; double[] v2 = new double[]{t.vertices[2].getX(), t.vertices[2].getY()}; double[] pv0 = get2DProjection(v0[0], v0[1], v1[0], v1[1], v2[0], v2[1]); double[] pv1 = get2DProjection(v1[0], v1[1], v0[0], v0[1], v2[0], v2[1]); double[] pv2 = get2DProjection(v2[0], v2[1], v0[0], v0[1], v1[0], v1[1]); Paint oldPaint = g2d.getPaint(); Area area = new Area(contour); area.add(new Area(stroke.createStrokedShape(contour))); GradientPaint gp = new GradientPaint((float) v0[0], (float) v0[1], t.colors[0], (float) pv0[0], (float) pv0[1], TRANSLUCENT_BLACK); g2d.setPaint(gp); g2d.fill(contour); gp = new GradientPaint((float) v1[0], (float) v1[1], t.colors[1], (float) pv1[0], (float) pv1[1], TRANSLUCENT_BLACK); g2d.setPaint(gp); g2d.fill(contour); gp = new GradientPaint((float) v2[0], (float) v2[1], t.colors[2], (float) pv2[0], (float) pv2[1], TRANSLUCENT_BLACK); g2d.setPaint(gp); g2d.fill(contour); g2d.setPaint(oldPaint); } /** * Draw a texture (ie a BufferedImage) in a triangle * @param g2d the Graphics2D where to draw * @param image the texture to apply * @param ximg the x-coordinates of the triangle to use in the texture * @param yimg the y-coordinates of the triangle to use in the texture * @param xdest the x-coordinates of the destination triangle * @param ydest the y-coordinates of the destination triangle * @param key the rendering hint to use for interpolation */ public static final void drawTriangleTexture(final Graphics2D g2d, final BufferedImage image, final double[] ximg, final double[] yimg, final double[] xdest, final double[] ydest, Object key) { try { double w = image.getWidth(); double h = image.getHeight(); Path2D.Double path = new Path2D.Double(); path.moveTo(xdest[0], ydest[0]); path.lineTo(xdest[1], ydest[1]); path.lineTo(xdest[2], ydest[2]); path.closePath(); Area area = new Area(path); area.add(new Area(stroke.createStrokedShape(path))); boolean is1d = is1d(ximg, yimg); // if we have a 1D texture we must slighlty modified the coordinates to use the algorithm below. if (checkSourceCoordinates(ximg, yimg)) { // three coordinates are the same in 1D texture int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); int index = (int) Math.floor(w * ximg[0]); Color color; if (index >= pixels.length) { color = new Color(pixels[pixels.length - 1]); } else if (index < 0) { color = new Color(pixels[0]); } else { color = new Color(pixels[index]); } //color = Color.PINK; g2d.setColor(color); g2d.fill(area); return; } AffineTransform translationDest = AffineTransform.getTranslateInstance(xdest[0], ydest[0]); AffineTransform translationImg = AffineTransform.getTranslateInstance(-w * ximg[0], -h * yimg[0]); AffineTransform toDest = new AffineTransform(xdest[1] - xdest[0], ydest[1] - ydest[0], xdest[2] - xdest[0], ydest[2] - ydest[0], 0, 0); AffineTransform fromImg = new AffineTransform(w * (ximg[1] - ximg[0]), h * (yimg[1] - yimg[0]), w * (ximg[2] - ximg[0]), h * (yimg[2] - yimg[0]), 0, 0).createInverse(); AffineTransform transformation = new AffineTransform(); transformation.concatenate(translationDest); transformation.concatenate(toDest); transformation.concatenate(fromImg); transformation.concatenate(translationImg); AffineTransform oldTransform = g2d.getTransform(); // For now we don't enter in this // SVGGraphics2D doesn't handle MultipleGradient :( if (false && is1d && key == RenderingHints.VALUE_INTERPOLATION_BILINEAR) { int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); float[] fractions = new float[pixels.length]; for (int i = 0; i < fractions.length; i++) { fractions[i] = (((float) i) / (fractions.length - 1)); } Color[] colors = new Color[pixels.length]; for (int i = 0; i < colors.length; i++) { colors[i] = new Color(pixels[i]); } LinearGradientPaint gradient = new LinearGradientPaint(new Point2D.Double(0, 0), new Point2D.Double(pixels.length, 0), fractions, colors, MultipleGradientPaint.CycleMethod.NO_CYCLE, MultipleGradientPaint.ColorSpaceType.SRGB, transformation); Shape oldClip = g2d.getClip(); g2d.clip(area); g2d.setPaint(gradient); g2d.fill(area); g2d.setClip(oldClip); } else { clamp(g2d, ximg, yimg, xdest, ydest, transformation, image); Object oldKey = g2d.getRenderingHint(RenderingHints.KEY_INTERPOLATION); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, key); g2d.setStroke(EMPTYSTROKE); Shape oldClip = g2d.getClip(); g2d.clip(area); g2d.drawImage(image, transformation, null); g2d.setClip(oldClip); if (oldKey != null) { g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, oldKey); } } g2d.setTransform(oldTransform); } catch (NoninvertibleTransformException e) { System.err.println(e); } } /** * Draw a texture (ie a BufferedImage) in a parallelogram * @param g2d the Graphics2D where to draw * @param image the texture to apply * @param ximg the x-coordinates of the parallelogram to use in the texture * @param yimg the y-coordinates of the parallelogram to use in the texture * @param xdest the x-coordinates of the destination parallelogram * @param ydest the y-coordinates of the destination parallelogram * @param key the rendering hint to use for interpolation */ public static final void drawParallelogramTexture(final Graphics2D g2d, final BufferedImage image, final double[] ximg, final double[] yimg, final double[] xdest, final double[] ydest, Object key) { try { Object oldKey = g2d.getRenderingHint(RenderingHints.KEY_INTERPOLATION); double w = image.getWidth(); double h = image.getHeight(); AffineTransform translationDest = AffineTransform.getTranslateInstance(xdest[0], ydest[0]); AffineTransform translationImg = AffineTransform.getTranslateInstance(-w * ximg[0], -h * yimg[0]); AffineTransform toDest = new AffineTransform(xdest[1] - xdest[0], ydest[1] - ydest[0], xdest[2] - xdest[0], ydest[2] - ydest[0], 0, 0); AffineTransform fromImg = new AffineTransform(w * (ximg[1] - ximg[0]), h * (yimg[1] - yimg[0]), w * (ximg[2] - ximg[0]), h * (yimg[2] - yimg[0]), 0, 0).createInverse(); AffineTransform transformation = new AffineTransform(); transformation.concatenate(translationDest); transformation.concatenate(toDest); transformation.concatenate(fromImg); transformation.concatenate(translationImg); AffineTransform oldTransform= g2d.getTransform(); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, key); g2d.drawImage(image, transformation, null); g2d.setTransform(oldTransform); if (oldKey != null) { g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, oldKey); } } catch (NoninvertibleTransformException e) { } } /** * Check and modify the coordinates if we have a 1D texture (i.e. all the y-coords are zero) * @param x the x-coordinates * @param y the y-coordinates */ private static final boolean checkSourceCoordinates(final double[] x, final double[] y) { if (is1d(x, y)) { if (!AbstractDrawable3DObject.isEqual(x[0], x[1]) && !AbstractDrawable3DObject.isEqual(x[1], x[2]) && !AbstractDrawable3DObject.isEqual(x[2], x[0])) { y[0] = 1; } else if (AbstractDrawable3DObject.isEqual(x[0], x[1]) && !AbstractDrawable3DObject.isEqual(x[1], x[2])) { y[0] = 1; } else if (AbstractDrawable3DObject.isEqual(x[0], x[2]) && !AbstractDrawable3DObject.isEqual(x[2], x[1])) { y[2] = 1; } else if (AbstractDrawable3DObject.isEqual(x[1], x[2]) && !AbstractDrawable3DObject.isEqual(x[2], x[0])) { y[2] = 1; } else { return true; } y[0] = !AbstractDrawable3DObject.isNull(y[0]) ? 1 : 0; y[1] = !AbstractDrawable3DObject.isNull(y[1]) ? 1 : 0; y[2] = !AbstractDrawable3DObject.isNull(y[2]) ? 1 : 0; } return false; } /** * Check if the triangle in texture is degenerate * @param x x-coordinates * @param y y-coordinates * @return true if 1d */ private static final boolean is1d(final double[] x, final double[] y) { return AbstractDrawable3DObject.isNull(y[0]) && AbstractDrawable3DObject.isNull(y[1]) && AbstractDrawable3DObject.isNull(y[2]); } private static final void clamp(Graphics2D g2d, double[] ximg, double[] yimg, double[] xdest, double[] ydest, AffineTransform transformation, BufferedImage image) { if (ximg[0] < 0 || ximg[1] < 0 || ximg[2] < 0 || ximg[0] > 1 || ximg[1] > 1 || ximg[2] > 1) { double w = image.getWidth(); double h = image.getHeight(); int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); Path2D.Double path = new Path2D.Double(); path.moveTo(w * ximg[0], h * yimg[0]); path.lineTo(w * ximg[1], h * yimg[1]); path.lineTo(w * ximg[2], h * yimg[2]); path.closePath(); Area tri = new Area(path); Rectangle2D bounds = tri.getBounds2D(); if (bounds.getX() < 0) { Area rect = new Area(new Rectangle2D.Double(bounds.getX(), bounds.getY(), -bounds.getX(), bounds.getHeight())); tri.intersect(rect); if (!tri.isEmpty()) { tri.transform(transformation); g2d.setColor(new Color(pixels[0])); g2d.fill(tri); } } if (bounds.getX() + bounds.getWidth() > w) { tri = new Area(path); Area rect = new Area(new Rectangle2D.Double(w, bounds.getY(), bounds.getX() + bounds.getWidth() - w, bounds.getHeight())); tri.intersect(rect); if (!tri.isEmpty()) { tri.transform(transformation); g2d.setColor(new Color(pixels[pixels.length -1])); g2d.fill(tri); } } } } /** * Get the projection in 2D of point A on line (BC) * @param A the point to project * @param B a point of the line * @param C an other point of the line (different of B) * @return the projected point */ private static final double[] get2DProjection(final double xA, final double yA, final double xB, final double yB, final double xC, final double yC) { final double xBC = xC - xB; final double yBC = yC - yB; final double n = xBC * xBC + yBC * yBC; final double s = (xBC * (xA - xB) + yBC * (yA - yB)) / n; return new double[]{xB + s * xBC, yB + s * yBC}; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/G2DStroke.java000066400000000000000000000051061212506735300315160ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.BasicStroke; import java.awt.Stroke; import java.util.HashMap; import java.util.Map; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; /** * @author Calixte DENIZET */ public class G2DStroke extends BasicStroke { private static final int[] array = new int[16]; private static final Stroke BASIC = new G2DStroke(1, null, 0); public G2DStroke(float lineWidth, float[] dash, float phase) { super(lineWidth, CAP_BUTT, JOIN_MITER, 10.0f, dash, phase); } public static Stroke getStroke(Appearance appearance, double dashPhase) { Appearance usedAppearance; if (appearance == null) { usedAppearance = new Appearance(); } else { usedAppearance = appearance; } float factor = usedAppearance.getLineWidth(); if (factor == 0) { return new G2DStroke(0, null, 0); } short pattern = usedAppearance.getLinePattern(); if (pattern == -1 ) { if (factor == 1) { return BASIC; } return new G2DStroke(factor, null, 0); } return new G2DStroke(factor, decodePattern(factor, pattern), (float) dashPhase); } private static final float[] decodePattern(final float factor, short pattern) { // If the pattern is 1111101011111010, from right to left it becomes // 0101111101011111, the first 0 is put on the right 1011111010111110 and it is converted into // 1, 1, 5, 1, 1, 1, 5, 1 int n = 0xFFFF & pattern; int i = 0; int t = Integer.numberOfTrailingZeros(n); n = (n >> t); int k = Integer.numberOfLeadingZeros(n) - 16; while (n != 0) { t = Integer.numberOfTrailingZeros(n); if (t == 0) { t = Integer.numberOfTrailingZeros(0xFFFF - n); } array[i++] = t; n = n >> t; } array[i] = k; float[] ret = new float[i + 1]; for (int j = 0; j <= i; j++) { ret[j] = ((float) array[j]) * factor; } return ret; } } InvalidPolygonException.java000066400000000000000000000012701212506735300345060ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; /** * @author Calixte DENIZET */ @SuppressWarnings(value = { "serial" }) public class InvalidPolygonException extends Exception { public InvalidPolygonException(String msg) { super(msg); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/Motor3D.java000066400000000000000000000503251212506735300312440ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.image.BufferedImage; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.Arrays; import java.util.List; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.clipping.ClippingPlane; import org.scilab.forge.scirenderer.implementation.g2d.G2DCanvas; import org.scilab.forge.scirenderer.implementation.g2d.buffers.G2DElementsBuffer; import org.scilab.forge.scirenderer.implementation.g2d.texture.G2DTextureDrawingTools; import org.scilab.forge.scirenderer.implementation.g2d.texture.G2DTextureManager; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry.FaceCullingMode; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Calixte DENIZET */ public class Motor3D { private Transformation transf; private Transformation singleTransf; private FaceCullingMode mode = FaceCullingMode.BOTH; private Graphics2D g2d; private Dimension dim; private G2DTextureDrawingTools textureDrawingTools; private G2DCanvas canvas; /** * Default constructor * @param g2d a Graphics2D object where to draw * @param dim the graphic dimensions */ public Motor3D(G2DCanvas canvas, Graphics2D g2d, Dimension dim) { this.canvas = canvas; this.g2d = g2d; this.dim = dim; this.textureDrawingTools = new G2DTextureDrawingTools(g2d); AbstractDrawable3DObject.resetDefaultPrecedence(); } public void setGraphics(Graphics2D g2d) { this.g2d = g2d; this.textureDrawingTools.setGraphics(g2d); } public void setAntialiased(boolean aa) { if (aa) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } else { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } } public boolean is2DView() { return canvas.getMainDrawer().is2DView(); } public void setClippingPlanes(List clippingPlanes) { Scene.setClippingPlanes(clippingPlanes); } /** * Set the face culling mode * @param mode the mode to set */ public void setFaceCullingMode(FaceCullingMode mode) { this.mode = mode; } /** * Set the current transformation * @param transf the transformation to set */ public void setTransformation(Transformation transf, Transformation single) { this.transf = transf; this.singleTransf = single; } public Transformation getCurrentTransformation() { return transf; } public Transformation getCurrentSingleTransformation() { return singleTransf; } /** * Reset this motor * @param color the filling color */ public void reset(Color color) { transf = null; mode = FaceCullingMode.BOTH; g2d.setColor(color); g2d.fillRect(0, 0, (int) dim.getWidth(), (int) dim.getHeight()); Scene.clear(); } /** * Clear the depth buffer */ public void clearDepth() { Scene.clearDepth(); } /** * Draw the scene in the Graphics2D */ public void draw() { Scene.drawRoot(g2d); Scene.clearAll(); G2DTextureManager.clear(); } public void drawTexture(DrawingTools drawingTools, BufferedImage image, Texture texture) { try { SpritedRectangle o = new SpritedRectangle(new Vector3d(0, 0, 0), transf, image, texture.getMagnificationFilter()); add(o); } catch (InvalidPolygonException e) { } } /** * Add the geometry to the scene * @param drawingTools the DrawingTools * @param geometry the geometry to draw * @param appearance the appearance to use */ public void draw(DrawingTools drawingTools, Geometry geometry, Appearance appearance) { setFaceCullingMode(geometry.getFaceCullingMode()); FloatBuffer vertexBuffer = geometry.getVertices().getData(); IntBuffer indicesBuffer = null;; if (geometry.getIndices() != null) { indicesBuffer = geometry.getIndices().getData(); } IntBuffer wireIndicesBuffer = null; if (geometry.getWireIndices() != null) { wireIndicesBuffer = geometry.getWireIndices().getData(); } FloatBuffer colorBuffer = null; if (geometry.getColors() != null) { colorBuffer = geometry.getColors().getData(); } FloatBuffer normalBuffer = null; if (geometry.getNormals() != null) { normalBuffer = geometry.getNormals().getData(); } Texture texture = appearance.getTexture(); FloatBuffer textureCoordinatesBuffer = null; BufferedImage image = null; if (texture != null && geometry.getTextureCoordinates() != null) { textureCoordinatesBuffer = geometry.getTextureCoordinates().getData(); image = ((G2DTextureManager.G2DTexture) texture).getImage(); } if (geometry.getFillDrawingMode() != Geometry.FillDrawingMode.NONE) { addTriangles(vertexBuffer, normalBuffer, colorBuffer, appearance.getFillColor(), indicesBuffer, textureCoordinatesBuffer, image, texture, geometry.getFillDrawingMode()); } if (geometry.getLineDrawingMode() != Geometry.LineDrawingMode.NONE) { if (appearance.getLineColor() == null) { addSegments(vertexBuffer, colorBuffer, null, wireIndicesBuffer, geometry.getLineDrawingMode(), appearance); } else { addSegments(vertexBuffer, null, appearance.getLineColor(), wireIndicesBuffer, geometry.getLineDrawingMode(), appearance); } } } public void draw(DrawingTools drawingTools, Texture texture, AnchorPosition anchor, ElementsBuffer positions, double rotationAngle) { FloatBuffer positionsBuffer = positions.getData(); float[] buffer; positionsBuffer.rewind(); if (positionsBuffer.hasArray()) { buffer = positionsBuffer.array(); } else { buffer = new float[positionsBuffer.limit()]; positionsBuffer.get(buffer); } Vector3d[] verticesArray = getMultiVectors(buffer, transf, false); for (Vector3d v : verticesArray) { try { SpritedRectangle o = new SpritedRectangle(v, texture, anchor, textureDrawingTools, rotationAngle); add(o); } catch (InvalidPolygonException e) { } } } public void draw(DrawingTools drawingTools, Texture texture, AnchorPosition anchor, Vector3d position, double rotationAngle) { try { add(new SpritedRectangle(transf.project(position), texture, anchor, textureDrawingTools, rotationAngle)); } catch (InvalidPolygonException e) { } } /** * Add a Triangle to the scene * @param tri the triangle to add */ private void add(Triangle tri) { Vector3d normal = tri.getNormal(); if (normal != null) { //normal = transf.projectDirection(normal); if ((mode == FaceCullingMode.CW && normal.getZ() > 0) || (mode == FaceCullingMode.CCW && normal.getZ() < 0) || mode == FaceCullingMode.BOTH) { Scene.addToRoot(is2DView(), tri); } } else { Scene.addToRoot(is2DView(), tri); } } /** * Add a segment to the scene * @param s the segment to add */ private void add(Segment s) { Scene.addToRoot(is2DView(), s); } private void add(SpritedRectangle sprite) { Scene.addToRoot(is2DView(), sprite); } /** * Get arrays from Buffer * @param vertices a buffer containing vertices * @param colors a buffer containing the colors * @param defaultColor the color to use when colors is null * @param indices a buffer containg the index of the vertices to retrieve * @return an array of length 2 containing the vertices array and the colors array */ private Object[] getArrays(FloatBuffer vertices, FloatBuffer colors, Color defaultColor, FloatBuffer textureCoords, IntBuffer indices) { float[] buffer; Vector3d[] verticesArray; Vector3d[] textureCoordsArray = null; Color[] colorsArray; vertices.rewind(); if (vertices.hasArray()) { buffer = vertices.array(); } else { buffer = new float[vertices.limit()]; vertices.get(buffer); } verticesArray = getMultiVectors(buffer, transf, false); if (colors != null) { colors.rewind(); if (colors.hasArray()) { buffer = colors.array(); } else { buffer = new float[colors.limit()]; colors.get(buffer); } colorsArray = getMultiColors(buffer); } else { colorsArray = new Color[vertices.limit()]; Arrays.fill(colorsArray, defaultColor); } if (textureCoords != null) { textureCoords.rewind(); if (textureCoords.hasArray()) { buffer = textureCoords.array(); } else { buffer = new float[textureCoords.limit()]; textureCoords.get(buffer); } textureCoordsArray = getMultiVectors(buffer); } if (indices != null) { indices.rewind(); int[] ind; if (indices.hasArray()) { ind = indices.array(); } else { ind = new int[indices.limit()]; indices.get(ind); } Vector3d[] va = new Vector3d[ind.length]; Color[] ca = new Color[ind.length]; Vector3d[] ta = null; if (textureCoords != null) { ta = new Vector3d[ind.length]; } for (int i = 0; i < ind.length; i++) { va[i] = verticesArray[ind[i]]; ca[i] = colorsArray[ind[i]]; if (ta != null) { ta[i] = textureCoordsArray[ind[i]]; } } verticesArray = va; colorsArray = ca; textureCoordsArray = ta; } return new Object[] {verticesArray, colorsArray, textureCoordsArray}; } /** * Convert the buffer vertices into vertices array and put the segments in the scene * @param vertices a buffer containing vertices * @param colors a buffer containing the colors * @param defaultColor the color to use when colors is null * @param indices a buffer containg the index of the vertices to retrieve * @param drawingMode the drawing mode * @param stroke the Stroke to use to draw a segment */ private void addSegments(FloatBuffer vertices, FloatBuffer colors, Color defaultColor, IntBuffer indices, Geometry.LineDrawingMode drawingMode, Appearance appearance) { Object[] arrays = getArrays(vertices, colors, defaultColor, null, indices); Vector3d[] verticesArray = (Vector3d[]) arrays[0]; Color[] colorsArray = (Color[]) arrays[1]; Vector3d[] v; Color[] c; double cumLength = 0; if (verticesArray.length <= 1) { return; } switch (drawingMode) { case SEGMENTS_STRIP : for (int i = 0; i < verticesArray.length - 1; i++) { v = new Vector3d[] {verticesArray[i], verticesArray[i + 1]}; c = new Color[] {colorsArray[i], colorsArray[i + 1]}; try { add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength))); cumLength += Segment.getLength(v); } catch (InvalidPolygonException e) { cumLength = 0; } } break; case SEGMENTS_LOOP : for (int i = 0; i < verticesArray.length - 1; i++) { v = new Vector3d[] {verticesArray[i], verticesArray[i + 1]}; c = new Color[] {colorsArray[i], colorsArray[i + 1]}; try { add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength))); cumLength += Segment.getLength(v); } catch (InvalidPolygonException e) { cumLength = 0; } } int n = verticesArray.length - 1; v = new Vector3d[] {verticesArray[n], verticesArray[0]}; c = new Color[] {colorsArray[n], colorsArray[0]}; try { add(new Segment(v, c, G2DStroke.getStroke(appearance, cumLength))); } catch (InvalidPolygonException e) { } break; case SEGMENTS : default : for (int i = 0; i < verticesArray.length - 1; i += 2) { v = new Vector3d[] {verticesArray[i], verticesArray[i + 1]}; c = new Color[] {colorsArray[i], colorsArray[i + 1]}; try { add(new Segment(v, c, G2DStroke.getStroke(appearance, 0))); } catch (InvalidPolygonException e) { } } break; } } /** * Convert the buffer vertices into vertices array and put the triangles in the scene * @param vertices a buffer containing vertices * @param normals a buffer containing the normals (not used) * @param colors a buffer containing the colors * @param defaultColor the color to use when colors is null * @param indices a buffer containg the index of the vertices to retrieve * @param drawingMode the drawing mode */ private void addTriangles(FloatBuffer vertices, FloatBuffer normals, FloatBuffer colors, Color defaultColor, IntBuffer indices, FloatBuffer textureCoords, final BufferedImage image, Texture texture, Geometry.FillDrawingMode drawingMode) { Object[] arrays = getArrays(vertices, colors, defaultColor, textureCoords, indices); Vector3d[] verticesArray = (Vector3d[]) arrays[0]; Color[] colorsArray = (Color[]) arrays[1]; Vector3d[] textureCoordsArray = (Vector3d[]) arrays[2]; Vector3d[] v; Color[] c; Texture.Filter filter = Texture.Filter.NEAREST; if (texture != null) { filter = texture.getMagnificationFilter(); } switch (drawingMode) { case TRIANGLE_FAN : for (int i = 1; i < verticesArray.length - 1; i++) { v = new Vector3d[] {verticesArray[0], verticesArray[i], verticesArray[i + 1]}; try { if (image == null) { c = new Color[] {colorsArray[0], colorsArray[i], colorsArray[i + 1]}; add(new Triangle(v, c, null)); } else { add(new Triangle(v, new Vector3d[] {textureCoordsArray[0], textureCoordsArray[i], textureCoordsArray[i + 1]}, image, filter)); } } catch (InvalidPolygonException e) { } } int n = verticesArray.length - 1; v = new Vector3d[] {verticesArray[0], verticesArray[n], verticesArray[1]}; try { if (image == null) { c = new Color[] {colorsArray[0], colorsArray[n], colorsArray[1]}; add(new Triangle(v, c, null)); } else { add(new Triangle(v, new Vector3d[] {textureCoordsArray[0], textureCoordsArray[n], textureCoordsArray[1]}, image, filter)); } } catch (InvalidPolygonException e) { } break; case TRIANGLE_STRIP : for (int i = 0; i < verticesArray.length - 2; i++) { v = new Vector3d[] {verticesArray[i], verticesArray[i + 1], verticesArray[i + 2]}; try { if (image == null) { c = new Color[] {colorsArray[i], colorsArray[i + 1], colorsArray[i + 2]}; add(new Triangle(v, c, null)); } else { add(new Triangle(v, new Vector3d[] {textureCoordsArray[i], textureCoordsArray[i + 1], textureCoordsArray[i + 2]}, image, filter)); } } catch (InvalidPolygonException e) { } } break; case TRIANGLES : default : for (int i = 0; i < verticesArray.length - 2; i += 3) { v = new Vector3d[] {verticesArray[i], verticesArray[i + 1], verticesArray[i + 2]}; try { if (image == null) { c = new Color[] {colorsArray[i], colorsArray[i + 1], colorsArray[i + 2]}; add(new Triangle(v, c, null)); } else { add(new Triangle(v, new Vector3d[] {textureCoordsArray[i], textureCoordsArray[i + 1], textureCoordsArray[i + 2]}, image, filter)); } } catch (InvalidPolygonException e) { } } break; } } /** * Convert an array of float into an array of Vector3d objects * @param vertices an array of float containing (vertices.length / G2DElementsBuffer.ELEMENT_SIZE) vectors coordinates * @param t the transformation to use for the projection * @param dir if true t.projectDirection() is used rather than t.project() * @return an array of Vector3d containg the vertices */ private static final Vector3d[] getMultiVectors(final float[] vertices, final Transformation t, final boolean dir) { Vector3d[] v = new Vector3d[vertices.length / G2DElementsBuffer.ELEMENT_SIZE]; if (dir) { int j = 0; for (int i = 0; i < v.length; i++) { v[i] = t.projectDirection(new Vector3d(vertices[j], vertices[j + 1], vertices[j + 2])); j += G2DElementsBuffer.ELEMENT_SIZE; } } else { int j = 0; for (int i = 0; i < v.length; i++) { v[i] = t.project(new Vector3d(vertices[j], vertices[j + 1], vertices[j + 2])); j += G2DElementsBuffer.ELEMENT_SIZE; } } return v; } /** * Convert an array of float into an array of Vector3d objects * @param vertices an array of float containing (vertices.length / G2DElementsBuffer.ELEMENT_SIZE) vectors coordinates * @return an array of Vector3d containg the vertices */ private static final Vector3d[] getMultiVectors(final float[] vertices) { Vector3d[] v = new Vector3d[vertices.length / G2DElementsBuffer.ELEMENT_SIZE]; int j = 0; for (int i = 0; i < v.length; i++) { v[i] = new Vector3d(vertices[j], vertices[j + 1], vertices[j + 2]); j += G2DElementsBuffer.ELEMENT_SIZE; } return v; } /** * Convert a float array into a Color array * @param colors a float array * @return an array of Color */ private static final Color[] getMultiColors(final float[] colors) { Color[] c = new Color[colors.length / G2DElementsBuffer.ELEMENT_SIZE]; int j = 0; Color prev = Color.BLACK; for (int i = 0; i < c.length; i++) { c[i] = new Color(colors[j], colors[j + 1], colors[j + 2], colors[j + 3]); if (prev.equals(c[i])) { c[i] = prev; } prev = c[i]; j += G2DElementsBuffer.ELEMENT_SIZE; } return c; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/PolyLine.java000066400000000000000000000052051212506735300315050ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.*; import java.awt.Color; import java.awt.Graphics2D; import java.util.ArrayList; import java.util.List; import org.scilab.forge.scirenderer.implementation.g2d.*; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Calixte DENIZET */ public class PolyLine {/* extends AbstractDrawable3DObject { private boolean monochromatic; private Stroke stroke; private Shape clip; public PolyLine(Vector3d[] vertices, Color[] colors, Stroke stroke, Shape clip) throws InvalidPolygonException { super(vertices, colors); this.monochromatic = isMonochromatic(colors); this.stroke = stroke; this.clip = clip; } @Override protected Path2D getProjectedPolyLine() { int i; Path2D.Double path = new Path2D.Double(); // Trim on the left for (i = 0; i < vertices.length; i++) { if (!AbstractDrawable3DObject.isNanOrInf(vertices[i])) { break; } } if (i < vertices.length) { path.moveTo(vertices[i].getX(), vertices[i].getY()); i++; boolean broken = false; for (; i < vertices.length; i++) { if (AbstractDrawable3DObject.isNanOrInf(vertices[i])) { if (!broken) { broken = true; } } else { if (broken) { broken = false; path.moveTo(vertices[i].getX(), vertices[i].getY()); } else { path.lineTo(vertices[i].getX(), vertices[i].getY()); } } } } return path; } public void draw(Graphics2D g2d) { Shape oldClip = g2d.getClip(); Stroke oldStroke = g2d.getStroke(); g2d.clip(clip); if (monochromatic) { g2d.setColor(colors[0]); g2d.setStroke(stroke); g2d.draw(getProjectedPolyLine()); } else { Vector3D start = null; Color color = null; double cumLen = 0; float[] dashArray = stroke.getDashArray(); float lwidth = stroke.getLineWidth(); for (int i = 0; i < vertices.length; i++) { if (AbstractDrawable3DObject.isNanOrInf(vertices[i])) { start = null; } else { if (start == null) { start = vertices[i]; color = colors[i]; } else { Stroke nstroke = new G2DStroke(lwidth, dashArray, cumLen); g2d.setStroke(nstroke); g2d.setColor(color); g2d.draw(new Line2D.Double(start.getX(), start.getY(), vertices[i].getX(), vertices[i].getY())); cumLen += Math.hypot(start.getX() - vertices[i].getX(), start.getY() - vertices[i].getY()); } } } } g2d.setClip(oldClip); g2d.setStroke(oldStroke); }*/ } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/Scene.java000066400000000000000000000170511212506735300310110ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.Graphics2D; import java.util.ArrayList; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Stack; import java.util.TreeSet; import org.scilab.forge.scirenderer.clipping.ClippingPlane; final class Scene { private static Set faces2d = new TreeSet(new Comparator() { public int compare(Scene o1, Scene o2) { if (o1.object.vertices[0].getZ() == o2.object.vertices[0].getZ()) { return o1.object.getPrecedence() - o2.object.getPrecedence(); } return (int) Math.signum(o2.object.vertices[0].getZ() - o1.object.vertices[0].getZ()); } public boolean equals(Object obj) { return this == obj; } }); private static List faces = new ArrayList(); private static List disabledFaces = new ArrayList(); private static List clippingPlanes; private static Stack stack = new Stack();; private List behind; private List onfront; private ConvexObject object; private boolean drawn; private Scene(final ConvexObject object) { this.object = object; } public static final void setClippingPlanes(final List clippingPlanes) { Scene.clippingPlanes = clippingPlanes; } private static final List breakOnClippingPlane(ConvexObject o) { List list = new ArrayList(); List tmp = new ArrayList(); list.add(o); if (clippingPlanes != null) { for (ClippingPlane clip : clippingPlanes) { if (clip.isEnable()) { tmp.clear(); for (ConvexObject co : list) { List l = co.breakObject(clip.getEquation()); if (l != null) { tmp.addAll(l); } } list.clear(); list.addAll(tmp); if (list.isEmpty()) { break; } } } } return list; } static final void addToRoot(final boolean is2D, final ConvexObject co) { List broken = breakOnClippingPlane(co); for (ConvexObject object : broken) { add(is2D, object); } } private static final void add(final boolean is2D, final ConvexObject object) { synchronized (faces) { Scene st = new Scene(object); if (is2D) { faces2d.add(st); } else { Set toRemove = new HashSet(); List toAdd = null; for (Scene face : faces) { if (face.object instanceof Triangle && object instanceof Segment) { if (((Triangle) face.object).addSegment((Segment) object)) { if (st != null) { toRemove.add(st); st = null; } } } else if (object instanceof Triangle && face.object instanceof Segment) { if (((Triangle) object).addSegment((Segment) face.object)) { toRemove.add(face); } } if (st != null) { int r = face.object.isBehind(st.object); if (r == 1) { // object is behind face.object addBehind(face, st); addOnFront(st, face); } else if (r == -1) { // face.object is behind object addBehind(st, face); addOnFront(face, st); } else if (r == 2) { // collision toAdd = face.object.breakObject(st.object); if (toAdd != null && !toAdd.isEmpty()) { toRemove.add(face); toRemove.add(st); st = null; break; } } } } if (st != null) { faces.add(st); } for (Scene s : toRemove) { faces.remove(s); if (s.onfront != null) { for (Scene ss : s.onfront) { ss.behind.remove(s); } } } if (toAdd != null) { for (ConvexObject co : toAdd) { add(is2D, co); } } } } } static final void clearDepth() { disabledFaces.addAll(faces); disabledFaces.addAll(faces2d); faces.clear(); faces2d.clear(); } static final void drawRoot(final Graphics2D g2d) { synchronized (faces) { for (Scene face : disabledFaces) { face.draw(g2d); } for (Scene face : disabledFaces) { face.drawn = false; } for (Scene face : faces) { face.draw(g2d); } for (Scene face : faces2d) { face.draw(g2d); } // code to help debug /*for (Scene face : faces) { face.drawn = false; } for (Scene face : faces) { if (face.object.marked) { face.object.draw(g2d); } }*/ } } static final void clear() { disabledFaces.clear(); faces.clear(); faces2d.clear(); stack.clear(); } static final void clearAll() { clear(); clippingPlanes.clear(); } private final void draw(final Graphics2D g2d) { if (stack.contains(this)) { this.object.addArea(stack.peek().object); return; } if (!drawn) { stack.push(this); drawn = true; if (behind != null && !behind.isEmpty()) { for (Scene face : behind) { face.draw(g2d); } } object.draw(g2d); stack.pop(); } } private static final void addBehind(Scene face, Scene s) { if (face.behind == null) { face.behind = new ArrayList(); } face.behind.add(s); } private static final void addOnFront(Scene face, Scene s) { if (face.onfront == null) { face.onfront = new ArrayList(); } face.onfront.add(s); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/Segment.java000066400000000000000000000155271212506735300313640ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Stroke; import java.awt.geom.Path2D; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.HashSet; import java.util.Set; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.tranformations.Vector4d; /** * @author Calixte DENIZET */ public class Segment extends ConvexObject implements Comparable { private Integer hash; protected Stroke stroke; protected List segmentOn; public Segment(Vector3d[] vertices, Color[] colors, Stroke stroke) throws InvalidPolygonException { super(vertices, colors); if (vertices.length != 2) { throw new InvalidPolygonException("Invalid segment: must have 2 vertices."); } this.stroke = stroke; } public Segment(Vector3d[] vertices, Color[] colors) throws InvalidPolygonException { this(vertices, colors, null); } public void setStroke(Stroke stroke) { this.stroke = stroke; } public double getLength() { return vertices[0].minus(vertices[1]).getNorm(); } public static double getLength(Vector3d[] vertices) { return vertices[0].minus(vertices[1]).getNorm(); } public void addConvexObject(ConvexObject co) { if (segmentOn == null) { segmentOn = new ArrayList(2); } segmentOn.add(co); } public void removeConvexObject(ConvexObject co) { if (segmentOn != null) { segmentOn.remove(co); } } public void replaceSegment(List segs) { if (segmentOn != null) { for (ConvexObject co : segmentOn) { Triangle t = (Triangle) co; t.replaceSegment(this, segs); } } } public boolean isIn2D() { return isNull(vertices[0].getZ()) && isNull(vertices[1].getZ()); } public boolean isInFront() { return isEqual(vertices[0].getZ(), -0.5) && isEqual(vertices[1].getZ(), -0.5); } @Override public int compareTo(Segment o) { if (equals(o)) { return 0; } return getPrecedence() - o.getPrecedence(); } @Override public boolean equals(Object o) { if (o instanceof Segment) { Segment s = (Segment) o; return (s.vertices[0].equals(vertices[0]) && s.vertices[1].equals(vertices[1]) && s.colors[0].equals(colors[0]) && s.colors[1].equals(colors[1])) || (s.vertices[1].equals(vertices[0]) && s.vertices[0].equals(vertices[1]) && s.colors[1].equals(colors[0]) && s.colors[0].equals(colors[1])); } return false; } @Override public int isBehind(ConvexObject o) { if (o instanceof Triangle && ((Triangle) o).isSegmentAcross(this)) { return 1; } return super.isBehind(o); } @Override public List breakObject(ConvexObject o) { if (o instanceof Triangle) { return ((Triangle) o).breakObject(this); } else if (o instanceof SpritedRectangle) { return ((SpritedRectangle) o).breakObject(this); } return null; } @Override public List breakObject(Vector4d v) { double[] vv = v.getData(); Vector3d np = new Vector3d(vv); boolean a = isBehind(vertices[0], np, vv[3]); boolean b = isBehind(vertices[1], np, vv[3]); if (a && b) { List list = new ArrayList(1); list.add(this); return list; } if (!a && !b) { return null; } double c = (vv[3] + vertices[1].scalar(np)) / v0.scalar(np); Vector3d p = Vector3d.getBarycenter(vertices[0], vertices[1], c, 1 - c); Color color = getColorsBarycenter(colors[0], colors[1], c, 1 - c); Vector3d[] vs = null; Color[] cs = null; if (a) { vs = new Vector3d[]{vertices[0], p}; cs = new Color[]{colors[0], color}; } if (b) { vs = new Vector3d[]{p, vertices[1]}; cs = new Color[]{color, colors[1]}; } try { List list = new ArrayList(1); list.add(new Segment(vs, cs, this.stroke)); return list; } catch (InvalidPolygonException e) { } return null; } public List breakObject(Vector3d p, Vector3d u, Vector3d n) { double c = vertices[1].minus(p).scalar(n) / v0.scalar(n); if (c > 0 && !isNull(c) && c < 1 && !isEqual(c, 1)) { List list = new ArrayList(2); Vector3d q = Vector3d.getBarycenter(vertices[0], vertices[1], c, 1 - c); Color color = getColorsBarycenter(colors[0], colors[1], c, 1 - c); try { list.add(new Segment(new Vector3d[]{vertices[0], q}, new Color[]{colors[0], color}, stroke)); list.add(new Segment(new Vector3d[]{q, vertices[1]}, new Color[]{color, colors[1]}, stroke)); return list; } catch (InvalidPolygonException e) { } } else { List list = new ArrayList(1); try { list.add(new Segment(new Vector3d[]{vertices[0], vertices[1]}, new Color[]{colors[0], colors[1]}, stroke)); return list; } catch (InvalidPolygonException e) { } } return null; } @Override public void draw(Graphics2D g2d) { if (segmentOn == null || segmentOn.isEmpty()) { Path2D polyline = getProjectedPolyLine(); g2d.setColor(colors[0]); Stroke oldStroke = g2d.getStroke(); if (oldStroke != stroke) { g2d.setStroke(stroke); } g2d.draw(polyline); if (oldStroke != stroke) { g2d.setStroke(oldStroke); } drawAreas(g2d); } } @Override public int hashCode() { if (hash == null) { hash = Arrays.hashCode(vertices) + 19 * Arrays.hashCode(colors); } return hash; } @Override public String toString() { return "Segment " + vertices[0].toString() + " " + vertices[1].toString() + " Precedence: " + getPrecedence(); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/SpritedRectangle.java000066400000000000000000000235371212506735300332210ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.Path2D; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import org.scilab.forge.scirenderer.implementation.g2d.texture.G2DTextureDrawingTools; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.tranformations.Vector4d; /** * @author Calixte DENIZET */ public class SpritedRectangle extends ConvexObject { private static final Color[] COLORS = new Color[]{Color.BLACK, Color.BLACK, Color.BLACK}; private Texture sprite; private BufferedImage image; private G2DTextureDrawingTools drawingTools; private double rotationAngle; private Texture.Filter filter; private Vector3d position; public SpritedRectangle(Vector3d vertex, Texture sprite, AnchorPosition anchor, G2DTextureDrawingTools drawingTools, double rotationAngle) throws InvalidPolygonException { super(getSpriteVertices(vertex, sprite, anchor), null); this.sprite = sprite; this.drawingTools = drawingTools; this.rotationAngle = rotationAngle; this.position = vertex; } public SpritedRectangle(Vector3d vertex, Transformation transf, BufferedImage image, Texture.Filter filter) throws InvalidPolygonException { super(getSpriteVertices(vertex, transf, image), null); this.image = image; this.filter = filter; this.position = vertex; } @Override public List breakObject(ConvexObject o) { if (o instanceof Triangle) { return breakObject((Triangle) o); } else if (o instanceof Segment) { return breakObject((Segment) o); } else if (o instanceof SpritedRectangle) { return breakObject((SpritedRectangle) o); } return null; } public List breakObject(Triangle o) { try { Vector3d[] v1 = new Vector3d[]{vertices[0], vertices[1], vertices[2]}; Vector3d[] v2 = new Vector3d[]{vertices[0], vertices[2], vertices[3]}; Triangle t1 = new Triangle(v1, COLORS); Triangle t2 = new Triangle(v2, COLORS); t1.setSprite(this); t2.setSprite(this); List list = new ArrayList(); if (o.isBehind(t1) == 2) { List list2 = o.breakObject(t1); if (list2 != null) { list.addAll(list2); } } else { list.add(t1); } if (o.isBehind(t2) == 2) { List list2 = o.breakObject(t2); if (list2 != null) { list.addAll(list2); } } else { list.add(t2); } return list; } catch (InvalidPolygonException e) { } return null; } public List breakObject(Segment o) { try { Vector3d[] v = new Vector3d[]{vertices[0], vertices[1], vertices[2]}; Triangle t1 = new Triangle(v, COLORS); t1.setSprite(this); v = new Vector3d[]{vertices[0], vertices[2], vertices[3]}; Triangle t2 = new Triangle(v, COLORS); t2.setSprite(this); List list = t1.breakObject(o); if (list != null) { list.add(t2); return list; } list = t2.breakObject(o); if (list != null) { list.add(t1); return list; } } catch (InvalidPolygonException e) { } return null; } public List breakObject(SpritedRectangle o) { try { Vector3d[] v1 = new Vector3d[]{vertices[0], vertices[1], vertices[2]}; Vector3d[] v2 = new Vector3d[]{vertices[0], vertices[2], vertices[3]}; Triangle t1 = new Triangle(v1, COLORS); Triangle t2 = new Triangle(v2, COLORS); t1.setSprite(this); t2.setSprite(this); List list = o.breakObject(t1); if (list == null) { list = o.breakObject(t2); } else { List list2 = o.breakObject(t2); if (list2 != null) { list.addAll(list2); } } return list; } catch (InvalidPolygonException e) { } return null; } public List breakObject(Vector4d v) { try { double[] vv = v.getData(); Vector3d np = new Vector3d(vv); int ret = isBehind(np, vv[3]); if (ret == 1) { List list = new ArrayList(); list.add(this); return list; } else if (ret == -1) { return null; } Vector3d[] v1 = new Vector3d[]{vertices[0], vertices[1], vertices[2]}; Vector3d[] v2 = new Vector3d[]{vertices[0], vertices[2], vertices[3]}; Triangle t1 = new Triangle(v1, COLORS); Triangle t2 = new Triangle(v2, COLORS); t1.setSprite(this); t2.setSprite(this); List list = t1.breakObject(v); if (list != null) { List list2 = t2.breakObject(v); if (list2 != null) { list.addAll(list2); } return list; } else { return t2.breakObject(v); } } catch (InvalidPolygonException e) { } return null; } private static Vector3d[] getSpriteVertices(Vector3d vertex, Transformation transf, BufferedImage image) { int w = image.getWidth(); int h = image.getHeight(); double x = vertex.getX(); double y = vertex.getY(); double z = vertex.getZ(); return new Vector3d[]{transf.project(new Vector3d(x, y, z)), transf.project(new Vector3d(x + w, y, z)), transf.project(new Vector3d(x + w, y + h, z)), transf.project(new Vector3d(x, y + h, z))}; } private static Vector3d[] getSpriteVertices(Vector3d vertex, Texture sprite, AnchorPosition anchor) { Dimension d = sprite.getDataProvider().getTextureSize(); double spriteWidth = d.getWidth(); double spriteHeight = d.getHeight(); double deltaX = 0; double deltaY = 0; switch (anchor) { case LEFT: deltaX = spriteWidth / 2; break; case LOWER_LEFT: deltaX = spriteWidth / 2; deltaY = spriteHeight / 2; break; case UPPER_LEFT: deltaX = spriteWidth / 2; deltaY = -spriteHeight / 2; break; case UP: deltaY = -spriteHeight / 2; break; case CENTER: break; case DOWN: deltaY = spriteHeight / 2; break; case RIGHT: deltaX = -spriteWidth / 2; break; case LOWER_RIGHT: deltaX = -spriteWidth / 2; deltaY = spriteHeight / 2; break; case UPPER_RIGHT: deltaX = -spriteWidth / 2; deltaY = -spriteHeight / 2; break; default: } double x = vertex.getX() + deltaX; double y = vertex.getY() - deltaY; double z = vertex.getZ(); return new Vector3d[]{new Vector3d(x - spriteWidth / 2, y - spriteHeight / 2, z), new Vector3d(x - spriteWidth / 2, y + spriteHeight / 2, z), new Vector3d(x + spriteWidth / 2, y + spriteHeight / 2, z), new Vector3d(x + spriteWidth / 2, y - spriteHeight / 2, z)}; } public Texture getSprite() { return sprite; } @Override public void draw(Graphics2D g2d) { if (sprite != null) { Path2D contour = getProjectedContour(); AffineTransform oldTransf = g2d.getTransform(); Stroke oldStroke = g2d.getStroke(); if (rotationAngle != 0) { g2d.translate(position.getX(), position.getY()); g2d.rotate(-rotationAngle * Math.PI / 180); g2d.translate(vertices[0].getX() - position.getX(), vertices[0].getY() - position.getY()); } else { g2d.translate(vertices[0].getX(), vertices[0].getY()); } drawingTools.accept(sprite); g2d.setTransform(oldTransf); g2d.setStroke(oldStroke); } else { Object key = filter == Texture.Filter.LINEAR ? RenderingHints.VALUE_INTERPOLATION_BILINEAR : RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR; DrawTools.drawParallelogramTexture(g2d, image, new double[]{0, 1, 1, 0}, new double[]{0, 0, 1, 1}, new double[]{vertices[3].getX(), vertices[2].getX(), vertices[1].getX(), vertices[0].getX()}, new double[]{vertices[3].getY(), vertices[2].getY(), vertices[1].getY(), vertices[0].getY()}, key); } } public String toString() { return "SpritedRectangle: " + vertices[0].toString() + " " + vertices[1].toString() + " " + vertices[2].toString() + " " + vertices[3].toString() + "\nPrecedence: " + precedence; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/motor/Triangle.java000066400000000000000000000524011212506735300315170ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.motor; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.Area; import java.awt.geom.Path2D; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.tranformations.Vector3d; import org.scilab.forge.scirenderer.tranformations.Vector4d; /** * @author Calixte DENIZET */ public class Triangle extends ConvexObject { private static final Color[] COLORS = new Color[]{Color.BLACK, Color.BLACK, Color.BLACK}; private static final Stroke stroke = new BasicStroke(1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); private static final Stroke EMPTYSTROKE = new BasicStroke(0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); private SpritedRectangle sprite; private BufferedImage image; private Vector3d[] textureCoords; private Texture.Filter filter; protected List segments; public Triangle(Vector3d[] vertices, Color[] colors, Vector3d normal) throws InvalidPolygonException { super(vertices, colors); if (vertices.length != 3) { throw new InvalidPolygonException("Invalid triangle: must have 3 vertices."); } } public Triangle(Vector3d[] vertices, Color[] colors) throws InvalidPolygonException { this(vertices, colors, null); } public Triangle(Vector3d[] vertices, Vector3d[] textureCoords, BufferedImage image, Texture.Filter filter) throws InvalidPolygonException { this(vertices, COLORS, null); this.textureCoords = textureCoords; this.image = image; this.filter = filter; } @Override public int isBehind(ConvexObject o) { if (o instanceof Segment && isSegmentAcross((Segment) o)) { return -1; } return super.isBehind(o); } public boolean isIn2D() { return vertices[0].getZ() == 0 && vertices[1].getZ() == 0 && vertices[2].getZ() == 0; } public boolean addSegment(Segment s) { if (isSegmentInside(s)) { if (segments == null) { segments = new ArrayList(3); } if (segments.contains(s)) { segments.remove(s); s.removeConvexObject(this); } segments.add(s); s.addConvexObject(this); return true; } return false; } public boolean pointOnVertices(Vector3d p) { return p.equals(vertices[0]) || p.equals(vertices[1]) || p.equals(vertices[2]); } public void removeSegment(Segment s) { if (segments != null) { segments.remove(s); s.removeConvexObject(this); } } public void replaceSegment(Segment s, List segs) { segments.remove(s); //s.removeConvexObject(this); for (Segment ss : segs) { if (segments.contains(ss)) { segments.remove(ss); ss.removeConvexObject(this); } segments.add(ss); ss.addConvexObject(this); } } @Override public List breakObject(ConvexObject o) { if (o instanceof Triangle) { return breakObject((Triangle) o); } else if (o instanceof Segment) { return breakObject((Segment) o); } else if (o instanceof SpritedRectangle) { return ((SpritedRectangle) o).breakObject(this); } return null; } public List breakObject(Triangle o) { Vector3d n = Vector3d.product(this.v0v1, o.v0v1); n = n.times(1 / n.getNorm2()); Vector3d u = Vector3d.product(o.v0v1, n); Vector3d v = Vector3d.product(n, this.v0v1); Vector3d p = Vector3d.getBarycenter(u, v, this.v0v1.scalar(this.vertices[0]), o.v0v1.scalar(o.vertices[0])); List list1 = breakTriangleOnLine(o, p, this.v0v1); List list2 = breakTriangleOnLine(this, p, o.v0v1); list1.addAll(list2); return list1; } public List breakObject(Segment o) { double c = this.getSegmentIntersection(o); if (Double.isNaN(c)) { return null; } List list = new ArrayList(5); Vector3d p = Vector3d.getBarycenter(o.vertices[0], o.vertices[1], c, 1 - c); Color cc = getColorsBarycenter(o.colors[0], o.colors[1], c, 1 - c); try { list.add(new Segment(new Vector3d[]{o.vertices[0], p}, new Color[]{o.colors[0], cc}, o.stroke)); list.add(new Segment(new Vector3d[]{p, o.vertices[1]}, new Color[]{cc, o.colors[1]}, o.stroke)); } catch (InvalidPolygonException e) { } List list1 = breakTriangleOnLine(this, p, Vector3d.product(v0v1, vertices[0].minus(p))); list.addAll(list1); return list; } protected void setSprite(SpritedRectangle sprite) { this.sprite = sprite; } protected SpritedRectangle getSprite() { return sprite; } @Override public void draw(Graphics2D g2d) { if (sprite != null) { Shape oldClip = g2d.getClip(); Path2D contour = getProjectedContour(); Area area = new Area(contour); // Trick to paint the triangle and its outline area.add(new Area(stroke.createStrokedShape(contour))); g2d.clip(area);//getProjectedContour()); sprite.draw(g2d); g2d.setClip(oldClip); } else if (image != null) { Object key = filter == Texture.Filter.LINEAR ? RenderingHints.VALUE_INTERPOLATION_BILINEAR : RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR; DrawTools.drawTriangleTexture(g2d, image, new double[]{textureCoords[0].getX(), textureCoords[1].getX(), textureCoords[2].getX()}, new double[]{textureCoords[0].getY(), textureCoords[1].getY(), textureCoords[2].getY()}, new double[]{vertices[0].getX(), vertices[1].getX(), vertices[2].getX()}, new double[]{vertices[0].getY(), vertices[1].getY(), vertices[2].getY()}, key); } else if (colors[0].equals(colors[1]) && colors[1].equals(colors[2])) { Path2D contour = getProjectedContour(); Area area = new Area(contour); // Trick to paint the triangle and its outline area.add(new Area(stroke.createStrokedShape(contour))); g2d.setStroke(EMPTYSTROKE); g2d.setColor(colors[0]); g2d.fill(area); } else { DrawTools.fillGouraud(g2d, this); } if (segments != null) { for (Segment s : segments) { s.removeConvexObject(this); s.draw(g2d); } } drawAreas(g2d); } @Override public List breakObject(Vector4d v) { double[] vv = v.getData(); Vector3d np = new Vector3d(vv); int ret = isBehind(np, vv[3]); if (ret == 1) { List list = new ArrayList(1); list.add(this); return list; } else if (ret == -1) { return null; } Vector3d n = Vector3d.product(this.v0v1, np); n = n.times(1 / n.getNorm2()); Vector3d u = Vector3d.product(np, n); Vector3d w = Vector3d.product(n, this.v0v1); Vector3d p = Vector3d.getBarycenter(u, w, this.v0v1.scalar(this.vertices[0]), -vv[3]); List list1 = breakTriangleOnLine(this, p, np); List list = new ArrayList(3); for (ConvexObject o : list1) { if (o.isBehind(np, vv[3]) == 1) { list.add(o); } } return list; } protected boolean isPointInside(final Vector3d v) { return isPointInside(v, true); } protected boolean isPointInside(final Vector3d v, final boolean checkCoplanarity) { Vector3d v2 = v.minus(vertices[0]); if (checkCoplanarity && !isNull(v2.scalar(v0v1))) { return false; } Vector3d v0v1v2 = Vector3d.product(v0v1, v2); double a = -v0v1v2.scalar(v1); if (a < 0 || isNull(a)) { return false; } double b = v0v1v2.scalar(v0); if (b < 0 || isNull(b)) { return false; } return a + b < nv0v1 || isEqual(a + b, nv0v1); } protected boolean isCoplanar(final Segment s) { double sc = vertices[0].scalar(v0v1); return isEqual(sc, s.vertices[0].scalar(v0v1)) && isEqual(sc, s.vertices[1].scalar(v0v1)); } protected boolean isCoplanar(final Triangle t) { double sc = vertices[0].scalar(v0v1); return isEqual(sc, t.vertices[0].scalar(v0v1)) && isEqual(sc, t.vertices[1].scalar(v0v1)) && isEqual(sc, t.vertices[2].scalar(v0v1)); } protected boolean isSegmentAcross(final Segment s) { if (!isCoplanar(s)) { // the segment and the triangle are not coplanar return false; } return check2DTrueIntersection(s); } protected boolean isSegmentInside(final Segment s) { if (!isCoplanar(s)) { // the segment and the triangle are not coplanar return false; } // Since there is a good probability that a segment is triangle border we check that if ((s.vertices[0].equals(vertices[0]) || s.vertices[0].equals(vertices[1]) || s.vertices[0].equals(vertices[2])) && (s.vertices[1].equals(vertices[0]) || s.vertices[1].equals(vertices[1]) || s.vertices[1].equals(vertices[2]))) { return true; } return isPointInside(s.vertices[0], false) || isPointInside(s.vertices[1], false) || check2DIntersection(s); } protected boolean isSegmentIntersects(final Segment s) { Vector3d v3 = s.vertices[0].minus(vertices[0]); Vector3d v4 = s.vertices[1].minus(vertices[0]); double c = v3.scalar(v0v1); if (Math.signum(c) == Math.signum(v4.scalar(v0v1))) { return false; } Vector3d v2 = s.vertices[0].minus(s.vertices[1]); Vector3d v1v2 = Vector3d.product(v1, v2); double a = v3.scalar(v1v2); double b = Vector3d.det(v3, v2, v0); double detv0v1v2 = v0.scalar(v1v2); double sign = Math.signum(detv0v1v2); return Math.signum(a) == sign && Math.signum(b) == sign && Math.signum(c) == sign && a + b <= detv0v1v2 && c <= detv0v1v2; } protected double getSegmentIntersection(final Segment s) { Vector3d v = s.vertices[1].minus(vertices[0]); double c = v.scalar(v0v1) / s.v0.scalar(v0v1); if (isNegativeOrNull(c) || isGreaterOrEqual(c, 1)) { return Double.NaN; } Vector3d p = Vector3d.getBarycenter(s.vertices[0], s.vertices[1], c, 1 - c); if (isPointInside(p, false)) { return c; } return Double.NaN; } protected static List breakSegmentOnTriangle(final Triangle t, final Segment s) { double c = t.getSegmentIntersection(s); if (Double.isNaN(c)) { return null; } List list = new ArrayList(2); Vector3d p = Vector3d.getBarycenter(s.vertices[0], s.vertices[1], c, 1 - c); Color cc = getColorsBarycenter(s.colors[0], s.colors[1], c, 1 - c); try { list.add(new Segment(new Vector3d[]{s.vertices[0], p}, new Color[]{s.colors[0], cc}, s.stroke)); list.add(new Segment(new Vector3d[]{p, s.vertices[1]}, new Color[]{cc, s.colors[1]}, s.stroke)); } catch (InvalidPolygonException e) { } return list; } /** * Break a triangle according to its intersection with a line containing p in the plane of the triangle and orthogonal to n * The triangle and the line are supposed to be coplanar. * @param t the triangle to break * @param p a point of the line * @param n a vector * @return a list of triangles */ protected static List breakTriangleOnLine(Triangle t, Vector3d p, Vector3d n) { // aP0+(1-a)P1 double a = t.vertices[1].minus(p).scalar(n) / t.v0.scalar(n); // bP0+(1-b)P2 double b = t.vertices[2].minus(p).scalar(n) / t.v1.scalar(n); // cP1+(1-c)P2 Vector3d v2 = t.vertices[2].minus(t.vertices[1]); double c = t.vertices[2].minus(p).scalar(n) / v2.scalar(n); List list = new ArrayList(3); int i = -1; int j = -1; int k = -1; double weight = -1; if (isNull(a)) { // We are on P1 i = 1; j = 2; k = 0; weight = b; } if (isNull(a - 1)) { // We are on P0 if (weight != -1) { list.add(t); return list; } else { i = 0; j = 1; k = 2; weight = c; } } if (isNull(b)) { // We are on P2 if (weight != -1) { list.add(t); return list; } else { i = 2; j = 0; k = 1; weight = a; } } if (i != -1) { if (weight >= 0 && weight <= 1) { // We break into two triangles Vector3d vb = Vector3d.getBarycenter(t.vertices[j], t.vertices[k], weight, 1 - weight); Color cb = getColorsBarycenter(t.colors[j], t.colors[k], weight, 1 - weight); Vector3d[] vertices1 = new Vector3d[]{t.vertices[i], t.vertices[j], vb}; Vector3d[] vertices2 = new Vector3d[]{t.vertices[i], vb, t.vertices[k]}; Color[] colors1 = new Color[]{t.colors[i], t.colors[j], cb}; Color[] colors2 = new Color[]{t.colors[i], cb, t.colors[k]}; Vector3d[] tvertices1 = null; Vector3d[] tvertices2 = null; if (t.textureCoords != null) { Vector3d tvb = Vector3d.getBarycenter(t.textureCoords[j], t.textureCoords[k], weight, 1 - weight); tvertices1 = new Vector3d[]{t.textureCoords[i], t.textureCoords[j], tvb}; tvertices2 = new Vector3d[]{t.textureCoords[i], tvb, t.textureCoords[k]}; } try { Triangle t1 = new Triangle(vertices1, colors1, null); t1.setSprite(t.getSprite()); list.add(t1); Triangle t2 = new Triangle(vertices2, colors2, null); t2.setSprite(t.getSprite()); list.add(t2); if (t.textureCoords != null) { t1.textureCoords = tvertices1; t2.textureCoords = tvertices2; t1.image = t2.image = t.image; t1.filter = t2.filter = t.filter; } } catch (InvalidPolygonException e) { } addSegments(list, t, p, Vector3d.product(t.v0v1, n), n); return list; } else { list.add(t); return list; } } Color cu, cv; Vector3d u, v; Vector3d tu = null, tv = null; // t has not been broken, so continue... if (a < 0 || a > 1) { i = 2; j = 0; k = 1; u = Vector3d.getBarycenter(t.vertices[1], t.vertices[2], c, 1 - c); v = Vector3d.getBarycenter(t.vertices[0], t.vertices[2], b, 1 - b); cu = getColorsBarycenter(t.colors[1], t.colors[2], c, 1 - c); cv = getColorsBarycenter(t.colors[0], t.colors[2], b, 1 - b); if (t.textureCoords != null) { tu = Vector3d.getBarycenter(t.textureCoords[1], t.textureCoords[2], c, 1 - c); tv = Vector3d.getBarycenter(t.textureCoords[0], t.textureCoords[2], b, 1 - b); } } else if (b < 0 || b > 1) { i = 1; j = 2; k = 0; u = Vector3d.getBarycenter(t.vertices[0], t.vertices[1], a, 1 - a); v = Vector3d.getBarycenter(t.vertices[1], t.vertices[2], c, 1 - c); cu = getColorsBarycenter(t.colors[0], t.colors[1], a, 1 - a); cv = getColorsBarycenter(t.colors[1], t.colors[2], c, 1 - c); if (t.textureCoords != null) { tu = Vector3d.getBarycenter(t.textureCoords[0], t.textureCoords[1], a, 1 - a); tv = Vector3d.getBarycenter(t.textureCoords[1], t.textureCoords[2], c, 1 - c); } } else { i = 0; j = 1; k = 2; u = Vector3d.getBarycenter(t.vertices[0], t.vertices[2], b, 1 - b); v = Vector3d.getBarycenter(t.vertices[0], t.vertices[1], a, 1 - a); cu = getColorsBarycenter(t.colors[0], t.colors[2], b, 1 - b); cv = getColorsBarycenter(t.colors[0], t.colors[1], a, 1 - a); if (t.textureCoords != null) { tu = Vector3d.getBarycenter(t.textureCoords[0], t.textureCoords[2], b, 1 - b); tv = Vector3d.getBarycenter(t.textureCoords[0], t.textureCoords[1], a, 1 - a); } } Vector3d[] vertices1 = new Vector3d[]{u, t.vertices[i], v}; Color[] colors1 = new Color[]{cu, t.colors[i], cv}; Vector3d[] vertices2 = new Vector3d[]{u, v, t.vertices[j]}; Color[] colors2 = new Color[]{cu, cv, t.colors[j]}; Vector3d[] vertices3 = new Vector3d[]{u, t.vertices[j], t.vertices[k]}; Color[] colors3 = new Color[]{cu, t.colors[j], t.colors[k]}; Vector3d[] tvertices1 = null; Vector3d[] tvertices2 = null; Vector3d[] tvertices3 = null; if (t.textureCoords != null) { tvertices1 = new Vector3d[]{tu, t.textureCoords[i], tv}; tvertices2 = new Vector3d[]{tu, tv, t.textureCoords[j]}; tvertices3 = new Vector3d[]{tu, t.textureCoords[j], t.textureCoords[k]}; } try { Triangle t1 = new Triangle(vertices1, colors1, null); t1.setSprite(t.getSprite()); list.add(t1); Triangle t2 = new Triangle(vertices2, colors2, null); t2.setSprite(t.getSprite()); list.add(t2); Triangle t3 = new Triangle(vertices3, colors3, null); t3.setSprite(t.getSprite()); list.add(t3); if (t.textureCoords != null) { t1.textureCoords = tvertices1; t2.textureCoords = tvertices2; t3.textureCoords = tvertices3; t1.image = t2.image = t3.image = t.image; t1.filter = t2.filter = t3.filter = t.filter; } } catch (InvalidPolygonException e) { } addSegments(list, t, p, Vector3d.product(t.v0v1, n), n); return list; } private static final void addSegments(List list, Triangle t, Vector3d p, Vector3d u, Vector3d n) { if (t.segments != null) { List segs = new ArrayList(); for (Segment s : t.segments) { s.removeConvexObject(t); List l = s.breakObject(p, u, n); if (l != null && !l.isEmpty()) { segs.addAll(l); s.replaceSegment(l); } } t.textureCoords = null; for (Segment s : segs) { for (ConvexObject tri : list) { ((Triangle) tri).addSegment(s); } } } } /** * Get the broken triangles in following the intersection of the planes containing t1 and t2. * The planes containing t1 and t2 are supposed to be secant. * @param t1 the first triangle * @param t2 the second triangle * @return an array of length 2 containing the resulting triangles for t1 and t2. */ protected static List breakIntersectingTriangles(Triangle t1, Triangle t2) { Vector3d n = Vector3d.product(t1.v0v1, t2.v0v1); n = n.times(1 / n.getNorm2()); Vector3d u = Vector3d.product(t2.v0v1, n); Vector3d v = Vector3d.product(n, t1.v0v1); Vector3d p = Vector3d.getBarycenter(u, v, t1.v0v1.scalar(t1.vertices[0]), t2.v0v1.scalar(t2.vertices[0])); List list1 = breakTriangleOnLine(t1, p, t2.v0v1); List list2 = breakTriangleOnLine(t2, p, t1.v0v1); list1.addAll(list2); return list1; } public String toString() { return "Triangle: " + vertices[0].toString() + " " + vertices[1].toString() + " " + vertices[2].toString() + "\nColor: " + colors[0] + "\nPrecedence: " + precedence; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/renderer/000077500000000000000000000000001212506735300275535ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/renderer/G2DRenderer.java000066400000000000000000000026531212506735300324670ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixre DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.renderer; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.renderer.Renderer; /** * @author Calixte DENIZET */ public class G2DRenderer implements Renderer { /** * The current drawer. */ private Drawer drawer; /** * Default constructor. * The constructor is package : only {@link G2DRendererManager} can instantiate this object. */ G2DRenderer() { } @Override public void setDrawer(Drawer drawer) { this.drawer = drawer; } @Override public Drawer getDrawer() { return drawer; } @Override public void reload() { // todo : on met qque chose ici ou pas ? } /** * Perform a draw to the given canvas. * @param drawingTools the given drawing tools. */ public void draw(DrawingTools drawingTools) { if (drawer != null) { drawer.draw(drawingTools); } } } G2DRendererManager.java000066400000000000000000000026041212506735300336770ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/renderer/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.renderer; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.renderer.Renderer; import org.scilab.forge.scirenderer.renderer.RendererManager; /** * @author Calixte DENIZET */ public class G2DRendererManager implements RendererManager { /** * Default constructor. */ public G2DRendererManager() { } @Override public Renderer createRenderer() { G2DRenderer newRenderer = new G2DRenderer(); return newRenderer; } @Override public void dispose(Renderer renderer) { } /** * Perform a draw with the given renderer to the given canvas.. * @param drawingTools the given drawing tools. * @param renderer the given renderer. */ public void draw(DrawingTools drawingTools, Renderer renderer) { if (renderer instanceof G2DRenderer) { ((G2DRenderer) renderer).draw(drawingTools); } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/texture/000077500000000000000000000000001212506735300274455ustar00rootroot00000000000000G2DTextureDrawingTools.java000066400000000000000000000160511212506735300345260ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/texture/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.texture; import org.scilab.forge.scirenderer.implementation.g2d.motor.G2DStroke; import org.scilab.forge.scirenderer.implementation.g2d.texture.G2DTextureManager; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.texture.TextEntity; import javax.swing.Icon; import javax.swing.JLabel; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.TextLayout; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; /** * * Implementation of {@link TextureDrawingTools}. * This implementation create a {@link TextureBufferedImage} an fill it with sprite drawing. * * @author Pierre Lando */ public class G2DTextureDrawingTools implements TextureDrawingTools { private Graphics2D g2d; /** * Default constructor. * @param width the image width. * @param height the image height. * @param useSquareTexture true if square texture is needed. */ public G2DTextureDrawingTools(Graphics2D g2d) { this.g2d = g2d; } public void setGraphics(Graphics2D g2d) { this.g2d = g2d; } public void accept(Texture texture) { G2DTextureManager.G2DTexture t = (G2DTextureManager.G2DTexture) texture; TextureDrawer drawer = t.getDrawer(); Dimension d = drawer.getTextureSize(); accept(drawer, (int) d.getWidth(), (int) d.getHeight()); } /** * Ask this image to accept a sprite drawer. * This image will contain the drawing of the given drawer. * @param spriteDrawer the given sprite drawer. */ public void accept(TextureDrawer textureDrawer, int width, int height) { // Change center coordinate to (0, 0). if (textureDrawer.getOriginPosition() == TextureDrawer.OriginPosition.CENTER) { g2d.translate(width / 2.0, height / 2.0); } boolean aa = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING) == RenderingHints.VALUE_ANTIALIAS_ON; if (!aa) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } textureDrawer.draw(this); if (!aa) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } } @Override public void drawPlus(int size, Appearance appearance) { if (size > 1) { int r = size / 2; int[] coords1 = new int[]{-r, 0, r, 0}; int[] coords2 = new int[]{0, -r, 0, r}; drawPolyline(coords1, appearance); drawPolyline(coords2, appearance); } else { fillDisc(0, 0, 1, appearance.getLineColor()); } } @Override public void drawPolyline(int[] coordinates, Appearance appearance) { if (coordinates.length == 2) { } int nbPoint = coordinates.length / 2; int[] xCoordinates = new int[nbPoint]; int[] yCoordinates = new int[nbPoint]; int k = 0; for (int i = 0; i < coordinates.length; i += 2) { xCoordinates[k] = coordinates[i]; yCoordinates[k] = coordinates[i + 1]; k++; } g2d.setColor(appearance.getLineColor()); g2d.setStroke(G2DStroke.getStroke(appearance, 0)); g2d.drawPolyline(xCoordinates, yCoordinates, nbPoint); } @Override public void fillPolygon(int[] coordinates, Appearance appearance) { int nbPoint = coordinates.length / 2; int[] xCoordinates = new int[nbPoint]; int[] yCoordinates = new int[nbPoint]; int k = 0; for (int i = 0; i < coordinates.length; i += 2) { xCoordinates[k] = coordinates[i]; yCoordinates[k] = coordinates[i + 1]; k++; } if (appearance.getFillColor().getAlphaAsFloat() != 0) { g2d.setColor(appearance.getFillColor()); g2d.fillPolygon(xCoordinates, yCoordinates, nbPoint); } if (!appearance.getLineColor().equals(appearance.getFillColor())) { int usedLength = coordinates.length - (coordinates.length % 2); int[] borderCoordinate = new int[usedLength + 2]; System.arraycopy(coordinates, 0, borderCoordinate, 0, usedLength); borderCoordinate[usedLength] = coordinates[0]; borderCoordinate[usedLength + 1] = coordinates[1]; drawPolyline(borderCoordinate, appearance); } } @Override public void drawCircle(int x, int y, int diameter, Appearance appearance) { g2d.setColor(appearance.getLineColor()); g2d.setStroke(G2DStroke.getStroke(appearance, 0)); double r = ((double) diameter) / 2; g2d.draw(new Ellipse2D.Double(x - r, y - r, diameter, diameter)); } @Override public void fillDisc(int x, int y, int diameter, Color color) { if (color.getAlphaAsFloat() != 0) { g2d.setColor(color); double r = ((double) diameter) / 2; g2d.fill(new Ellipse2D.Double(x - r, y - r, diameter, diameter)); } } @Override public void draw(TextEntity textEntity, int x, int y) { if (textEntity != null && textEntity.isValid()) { if (textEntity.isTextAntiAliased()) { g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); } else { g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); } if (textEntity.isTextUseFractionalMetrics()) { g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); } else { g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF); } g2d.setColor(textEntity.getTextColor()); TextLayout textLayout = new TextLayout(textEntity.getText(), textEntity.getFont(), g2d.getFontRenderContext()); Rectangle2D bounds = textLayout.getBounds(); g2d.setFont(textEntity.getFont()); g2d.drawString(textEntity.getText(), (float) (x - bounds.getX()), (float) (y - bounds.getY())); } } @Override public void draw(Icon icon, int x, int y) { icon.paintIcon(new JLabel(), g2d, x, y); } @Override public void clear(Color color) { } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/g2d/texture/G2DTextureManager.java000066400000000000000000000125371212506735300335500ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.g2d.texture; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.implementation.g2d.G2DCanvas; import org.scilab.forge.scirenderer.implementation.g2d.G2DDrawingTools; import org.scilab.forge.scirenderer.texture.AbstractTexture; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureManager; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; /** * @author Calixte DENIZET */ public class G2DTextureManager implements TextureManager { private static Map images = new HashMap(); public G2DTextureManager(G2DCanvas canvas) { } public static void clear() { images.clear(); } /** * Draw the given texture. * @param drawingTools used drawing tools. * @param texture the texture too drawn. * @throws org.scilab.forge.scirenderer.SciRendererException if the texture is invalid. */ public void draw(G2DDrawingTools drawingTools, Texture texture) throws SciRendererException { if (texture instanceof G2DTexture) { ((G2DTexture) texture).draw(drawingTools); } } @Override public Texture createTexture() { return new G2DTexture(); } @Override public void dispose(Collection textures) { for (Texture texture : textures) { dispose(texture); } } @Override public void dispose(Texture texture) { if (texture instanceof G2DTexture) { ((G2DTexture) texture).dispose(); } } /** * Inner class for {@link Texture} implementation. */ public class G2DTexture extends AbstractTexture implements Texture { private ImageBuffer image; private TextureDrawer drawer; /** * Default constructor. */ public G2DTexture() { } public void dispose() { images.remove(image); } @Override public void setDrawer(TextureDrawer drawer) { this.drawer = drawer; super.setDrawer(drawer); } public TextureDrawer getDrawer() { return drawer; } public void draw(G2DDrawingTools drawingTools) { drawingTools.getMotor3D().drawTexture(drawingTools, getImage(), this); } public BufferedImage getImage() { if (image == null) { Dimension textureSize = getDataProvider().getTextureSize(); ByteBuffer buffer = getDataProvider().getData(); byte[] bbuffer; if (buffer.hasArray()) { bbuffer = buffer.array(); } else { bbuffer = new byte[buffer.capacity()]; buffer.get(bbuffer); } ImageBuffer ib1 = new ImageBuffer(bbuffer, (int) textureSize.getWidth(), (int) textureSize.getHeight()); ImageBuffer ib2 = images.get(ib1); if (ib2 == null) { images.put(ib1, ib1); ib2 = ib1; } image = ib2; } return image.getImage(); } } private static class ImageBuffer { private byte[] buffer; private int hash; private int width; private int height; private BufferedImage image; ImageBuffer(byte[] buffer, int width, int height) { this.buffer = buffer; this.hash = Arrays.hashCode(buffer); this.width = width; this.height = height; } BufferedImage getImage() { if (image == null) { int[] ibuffer = new int[buffer.length / 4]; for (int i = 0; i < ibuffer.length; i++) { final int A = buffer[4 * i + 3] & 0xFF; final int R = buffer[4 * i] & 0xFF; final int G = buffer[4 * i + 1] & 0xFF; final int B = buffer[4 * i + 2] & 0xFF; ibuffer[i] = (A << 24) | (R << 16) | (G << 8) | B; } image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); image.setRGB(0, 0, width, height, ibuffer, 0, width); } return image; } @Override public int hashCode() { return hash; } @Override public boolean equals(Object o) { if (o instanceof ImageBuffer) { ImageBuffer mfb = (ImageBuffer) o; return Arrays.equals(buffer, mfb.buffer); } return false; } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/000077500000000000000000000000001212506735300262245ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/HardwareFailException.java000066400000000000000000000015211212506735300332760ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl; /** * * An exception to throw when hardware is to bad. * * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public class HardwareFailException extends Exception { /** * Default constructor. * @param message the message associated with this exception. */ public HardwareFailException(String message) { super(message); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/JoGLCanvas.java000066400000000000000000000320461212506735300310230ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.implementation.jogl.buffers.JoGLBuffersManager; import org.scilab.forge.scirenderer.implementation.jogl.picking.JoGLPickingManager; import org.scilab.forge.scirenderer.implementation.jogl.renderer.JoGLRendererManager; import org.scilab.forge.scirenderer.implementation.jogl.texture.JoGLTextureManager; import org.scilab.forge.scirenderer.picking.PickingManager; import com.jogamp.opengl.util.awt.ImageUtil; import com.jogamp.opengl.util.awt.Screenshot; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.lang.reflect.InvocationTargetException; import java.util.concurrent.Semaphore; import javax.media.opengl.DebugGL2; import javax.media.opengl.GL2; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import javax.media.opengl.GLEventListener; import javax.media.opengl.GLException; import javax.media.opengl.GLPbuffer; import javax.media.opengl.GLProfile; import javax.swing.SwingUtilities; import jogamp.opengl.GLContextImpl; /** * JoGL implementation of a Canvas. * * @author Pierre Lando */ public final class JoGLCanvas implements Canvas, GLEventListener { private static final double[][][] ANTI_ALIASING_JITTER = { {{0.0, 0.0}}, {{0.5, 0.5}, {0.5, -0.5}}, { { -0.25, -0.5}, {0.25, 0.5}, {0.75, -0.5}, {0.25, 0.5} }, { {0.125, -0.125}, { -0.875, 0.875}, { -0.375, 0.375}, {0.375, 0.625}, {0.625, -0.625}, {0.875, 0.125}, { -0.125, -0.875}, { -0.625, -0.375} }, { { -0.25, -0.125}, {0.25, -0.875}, {0.75, -0.625}, { -0.75, -0.875}, { -0.25, 0.375}, {0.75, -0.125}, {0.25, 0.125}, { -0.25, 0.875}, {0.25, -0.375}, { -0.75, 0.125}, { -0.75, 0.625}, { -0.25, -0.625}, {0.75, 0.875}, {0.75, 0.375}, { -0.75, -0.375}, {0.25, 0.625} } }; private final GLAutoDrawable autoDrawable; private final JoGLDrawingTools drawingTools; private final JoGLParameters parameters; private final JoGLBuffersManager buffersManager; private final JoGLRendererManager rendererManager; private final JoGLPickingManager pickingManager; private final JoGLTextureManager textureManager; private final CanvasAnimator canvasAnimator; private boolean isOffscreen; private DebugGL2 debug; private boolean isValid = true; private boolean displayFinished; /** The current mainDrawer. */ private Drawer mainDrawer; /** The anti-aliasing level */ private int antiAliasingLevel = 0; /** * Default constructor. * @param autoDrawable the JoGL autoDrawable this canvas depend on. */ JoGLCanvas(GLAutoDrawable autoDrawable) { this.autoDrawable = autoDrawable; parameters = new JoGLParameters(); buffersManager = new JoGLBuffersManager(); rendererManager = new JoGLRendererManager(); drawingTools = new JoGLDrawingTools(this); pickingManager = new JoGLPickingManager(this); textureManager = new JoGLTextureManager(this); autoDrawable.addGLEventListener(this); canvasAnimator = new CanvasAnimator(autoDrawable); canvasAnimator.redraw(); } /** * Constructor for offscreen rendering * @param width the width * @param height the height */ JoGLCanvas(int width, int height) { this(getOffscreenDrawable(width, height)); isOffscreen = true; } public void setDebugMode(boolean debug) { if (debug) { this.debug = new DebugGL2(autoDrawable.getGL().getGL2()); } else { this.debug = null; } } // Implementation of getter & setter from Canvas. @Override public void setMainDrawer(Drawer mainDrawer) { this.mainDrawer = mainDrawer; } @Override public Drawer getMainDrawer() { return mainDrawer; } @Override public JoGLRendererManager getRendererManager() { return rendererManager; } @Override public JoGLBuffersManager getBuffersManager() { return buffersManager; } @Override public PickingManager getPickingManager() { return pickingManager; } @Override public JoGLTextureManager getTextureManager() { return textureManager; } @Override public int getWidth() { return autoDrawable.getWidth(); } @Override public int getHeight() { return autoDrawable.getHeight(); } @Override public Dimension getDimension() { return new Dimension(autoDrawable.getWidth(), autoDrawable.getHeight()); } @Override public void redraw() { canvasAnimator.redraw(); } @Override public void redrawAndWait() { try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { autoDrawable.display(); } }); } catch (Exception e) { } } @Override public void waitImage() { canvasAnimator.waitEndOfDrawing(); } @Override public int getAntiAliasingLevel() { return antiAliasingLevel; } @Override public void setAntiAliasingLevel(int antiAliasingLevel) { this.antiAliasingLevel = antiAliasingLevel; } // JoGLCanvas specific getter. /** * Return the OpenGl context. * @return the OpenGl context. */ public GL2 getGl() { if (debug == null) { return autoDrawable.getGL().getGL2(); } else { return debug; } } /** * Return the rendering parameters. * @return the rendering parameters. */ public JoGLParameters getJoGLParameters() { return parameters; } /** * Get an image from the autoDrawable * @return an image */ public BufferedImage getImage() { while (!canvasAnimator.isDrawFinished() || !displayFinished) { try { Thread.sleep(10); } catch (InterruptedException e) { break; } } final BufferedImage[] image = new BufferedImage[1]; final GLContext context = autoDrawable.getContext(); try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { context.makeCurrent(); image[0] = Screenshot.readToBufferedImage(autoDrawable.getWidth(), autoDrawable.getHeight()); context.release(); } }); } catch (InterruptedException e) { } catch (InvocationTargetException e) { System.err.println(e); e.printStackTrace(); } boolean needFlip; try { needFlip = !((GLContextImpl) context).offscreenImageNeedsVerticalFlip(); } catch (GLException e) { needFlip = false; } if (needFlip) { // Need to flip image when Windows uses an OpenGL software renderer ImageUtil.flipImageVertically(image[0]); } return image[0]; } /** * Destroy the GLPbuffer */ public void destroy() { if (isOffscreen) { ((GLPbuffer) autoDrawable).destroy(); } try { isValid = false; canvasAnimator.finalize();//Thread.dumpStack(); } catch (Throwable e) { // TODO: handle exception } } /** * Creates a GLPbuffer for an offscreen rendering * @param width the width * @param height the height * @return a GLPbuffer */ private static GLAutoDrawable getOffscreenDrawable(int width, int height) { GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory(); GLCapabilities capabilities = new GLCapabilities(GLProfile.getDefault()); return factory.createGLPbuffer(null, capabilities, null, width, height, null); } // Implementation of function from GLEventListener. @Override public void display(GLAutoDrawable glAutoDrawable) { if (isValid) { displayFinished = false; GL2 gl = getGl().getGL2(); buffersManager.glSynchronize(gl); rendererManager.glSynchronize(gl); drawingTools.glSynchronize(gl); if (mainDrawer != null) { gl.glEnable(GL2.GL_DEPTH_TEST); gl.glDepthFunc(GL2.GL_LEQUAL); // Set to less equal to allow last drawn object to be on the top. if ((antiAliasingLevel > 0) && (antiAliasingLevel < 5) && (drawingTools.getGLCapacity().isAccumulationBufferPresent())) { org.scilab.forge.scirenderer.renderer.Renderer renderer = rendererManager.createRenderer(); renderer.setDrawer(mainDrawer); double[][] jitter = ANTI_ALIASING_JITTER[antiAliasingLevel]; Dimension dimension = getDimension(); gl.glClear(GL2.GL_ACCUM_BUFFER_BIT); for (double[] aJitter : jitter) { drawingTools.glSynchronize(gl); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); gl.glTranslated(aJitter[0] / dimension.getWidth(), aJitter[1] / dimension.getHeight(), 0.); gl.glClear(GL2.GL_DEPTH_BUFFER_BIT); rendererManager.draw(drawingTools, renderer); //mainDrawer.draw(drawingTools); gl.glReadBuffer(GL2.GL_BACK); gl.glAccum(GL2.GL_ACCUM, 1f / jitter.length); } rendererManager.dispose(drawingTools, renderer); gl.glDrawBuffer(GL2.GL_BACK); gl.glAccum(GL2.GL_RETURN, 1.0f); } else { gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); gl.glClear(GL2.GL_DEPTH_BUFFER_BIT); mainDrawer.draw(drawingTools); } } pickingManager.glConsume(drawingTools); displayFinished = true; } } @Override public void init(GLAutoDrawable glAutoDrawable) { textureManager.glReload(); buffersManager.glReload(); rendererManager.glReload(); } @Override public void reshape(GLAutoDrawable glAutoDrawable, int x, int y, int width, int height) { } @Override public void dispose(GLAutoDrawable drawable) { } /** * this class manage asynchronous scene drawing. */ private class CanvasAnimator implements Runnable { private final Semaphore semaphore = new Semaphore(1); private final Thread thread; private final GLAutoDrawable autoDrawable; private boolean running = true; public CanvasAnimator(GLAutoDrawable autoDrawable) { this.autoDrawable = autoDrawable; this.thread = new Thread(this); thread.start(); //System.err.println("[DEBUG] nb threads = "+Thread.activeCount()); } @Override public void finalize() throws Throwable { running = false; // we increment the semaphore to allow run() to unlock it and to be sure // to go out. semaphore.release(); autoDrawable.destroy(); super.finalize(); } public synchronized boolean isDrawFinished() { return semaphore.availablePermits() == 0; } /** Ask the animator to perform a draw later. */ public synchronized void redraw() { semaphore.release(); } /** Wait until a drawing has been performed */ public void waitEndOfDrawing() { semaphore.drainPermits(); } @Override public void run() { while (running) { try { semaphore.acquire(); semaphore.drainPermits(); if (running) { autoDrawable.display(); } } catch (InterruptedException e) { if (running) { Thread.currentThread().interrupt(); } break; } catch (GLException e) { if (running) { throw e; } break; } } } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/JoGLCanvasFactory.java000066400000000000000000000025041212506735300323470ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl; import org.scilab.forge.scirenderer.Canvas; import javax.media.opengl.GLAutoDrawable; /** * @author Pierre Lando */ public final class JoGLCanvasFactory { /** * Private constructor. * This is an utility class. */ private JoGLCanvasFactory() { } /** * Create a canvas from an auto drawable object. * @param autoDrawable the auto drawable object. * @return a canvas based on the given auto drawable object. */ public static Canvas createCanvas(final GLAutoDrawable autoDrawable) { return new JoGLCanvas(autoDrawable); } /** * Create a canvas for an offscreen rendering. * @param width the width * @param height the height * @return a canvas. */ public static Canvas createCanvas(final int width, final int height) { return new JoGLCanvas(width, height); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/JoGLCapacity.java000066400000000000000000000055751212506735300313540ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl; import javax.media.opengl.GL2; /** * This class store current OpenGl context capacity. * * @author Pierre Lando */ public class JoGLCapacity { /** The actual aliased point size range. */ private final float[] aliasedPointSizeRange = new float[] {0, 0}; /** The actual light number. */ private final int[] lightNumber = new int[] {8}; /** The actual light number. */ private final int[] clippingPlaneNumber = new int[] {6}; /** Maximum texture size. */ private final int[] textureSize = new int[] {64}; /** Accumulation buffer presence */ private boolean accumulationBufferPresent = false; /** * Default constructor. * The constructor is package because, only {@link JoGLDrawingTools} use this class. */ JoGLCapacity() { } /** * Reset the OpenGl capacity from the given context. * @param gl the given OpenGl context. */ void glReload(GL2 gl) { gl.glGetFloatv(GL2.GL_ALIASED_POINT_SIZE_RANGE, aliasedPointSizeRange, 0); gl.glGetIntegerv(GL2.GL_MAX_CLIP_PLANES, clippingPlaneNumber, 0); gl.glGetIntegerv(GL2.GL_MAX_LIGHTS, lightNumber, 0); gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_SIZE, textureSize, 0); int[] nbAccumulationBits = {0, 0, 0}; gl.glGetIntegerv(GL2.GL_ACCUM_RED_BITS, nbAccumulationBits, 0); gl.glGetIntegerv(GL2.GL_ACCUM_GREEN_BITS, nbAccumulationBits, 1); gl.glGetIntegerv(GL2.GL_ACCUM_BLUE_BITS, nbAccumulationBits, 2); if (nbAccumulationBits[0] == 0 || nbAccumulationBits[1] == 0 || nbAccumulationBits[2] == 0) { // accumulation buffers not there accumulationBufferPresent = false; } else { accumulationBufferPresent = true; } } /** * Return the aliased point size range. * The returned array had two elements. * @return the aliased point size range. */ public float[] getAliasedPointSizeRange() { return aliasedPointSizeRange.clone(); } /** * Return the number of available light. * @return the number of available light. */ public int getLightNumber() { return lightNumber[0]; } public int getClippingPlaneNumber() { return clippingPlaneNumber[0]; } public int getMaximumTextureSize() { return textureSize[0]; } public boolean isAccumulationBufferPresent() { return accumulationBufferPresent; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/JoGLDrawingTools.java000066400000000000000000000145701212506735300322260ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.clipping.ClippingManager; import org.scilab.forge.scirenderer.implementation.jogl.clipping.JoGLClippingManager; import org.scilab.forge.scirenderer.implementation.jogl.drawer.JoGLShapeDrawer; import org.scilab.forge.scirenderer.implementation.jogl.lightning.JoGLLightManager; import org.scilab.forge.scirenderer.lightning.LightManager; import org.scilab.forge.scirenderer.renderer.Renderer; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.tranformations.TransformationManager; import org.scilab.forge.scirenderer.tranformations.TransformationManagerImpl; import org.scilab.forge.scirenderer.tranformations.TransformationManagerListener; import org.scilab.forge.scirenderer.tranformations.Vector3d; import javax.media.opengl.GL2; /** * * JoGl implementation of the DrawingTools. * * @author Pierre Lando */ public class JoGLDrawingTools implements DrawingTools { private final JoGLCapacity capacity = new JoGLCapacity(); private final TransformationManager transformationManager; private final JoGLLightManager lightManager; private final JoGLClippingManager clippingManager; private final JoGLCanvas canvas; private GL2 gl; /** * Default constructor. * @param canvas the canvas where this drawing tools live. */ JoGLDrawingTools(JoGLCanvas canvas) { this.transformationManager = new TransformationManagerImpl(canvas); this.lightManager = new JoGLLightManager(this); this.clippingManager = new JoGLClippingManager(this); this.canvas = canvas; transformationManager.addListener(new TransformationManagerListener() { @Override public void transformationChanged(TransformationManager transformationManager) { gl.glMatrixMode(GL2.GL_MODELVIEW); if (transformationManager.isUsingSceneCoordinate()) { gl.glLoadMatrixd(transformationManager.getTransformation().getMatrix(), 0); } else { gl.glLoadMatrixd(transformationManager.getWindowTransformation().getMatrix(), 0); } } }); } /** * Synchronise to the given OpenGl context. * @param gl the OpenGL context. */ void glSynchronize(GL2 gl) { this.gl = gl; transformationManager.reset(); capacity.glReload(gl); lightManager.reload(); clippingManager.reload(); } @Override public JoGLCanvas getCanvas() { return canvas; } /** * Return the OpenGl context. * @return the OpenGl context. */ public GL2 getGl() { return gl; } /** * Return the OpenGl capacity of this canvas. * @return the OpenGl capacity of this canvas. */ public JoGLCapacity getGLCapacity() { return capacity; } @Override public TransformationManager getTransformationManager() { return transformationManager; } @Override public LightManager getLightManager() { return lightManager; } @Override public ClippingManager getClippingManager() { return clippingManager; } @Override public void clear(Color color) { gl.glClearColor(color.getRedAsFloat(), color.getGreenAsFloat(), color.getBlueAsFloat(), 1.f); gl.glClear(GL2.GL_COLOR_BUFFER_BIT); } @Override public void clear(java.awt.Color color) { float[] colorData = color.getRGBColorComponents(null); gl.glClearColor(colorData[0], colorData[1], colorData[2], 1f); gl.glClear(GL2.GL_COLOR_BUFFER_BIT); } @Override public void clearDepthBuffer() { gl.glClear(GL2.GL_DEPTH_BUFFER_BIT); } @Override public void draw(Renderer renderer) { canvas.getRendererManager().draw(this, renderer); } @Override public void draw(Geometry geometry) throws SciRendererException { JoGLShapeDrawer.getDrawer().draw(this, geometry, Appearance.getDefault()); } @Override public void draw(Geometry geometry, Appearance appearance) throws SciRendererException { JoGLShapeDrawer.getDrawer().draw(this, geometry, appearance); } @Override public void draw(Texture texture) throws SciRendererException { canvas.getTextureManager().draw(this, texture); } @Override public void draw(Texture texture, AnchorPosition anchor, ElementsBuffer positions) throws SciRendererException { canvas.getTextureManager().draw(this, texture, anchor, positions, 0); } @Override public void draw(Texture texture, AnchorPosition anchor, ElementsBuffer positions, double rotationAngle) throws SciRendererException { canvas.getTextureManager().draw(this, texture, anchor, positions, rotationAngle); } @Override public void draw(Texture texture, AnchorPosition anchor, Vector3d position) throws SciRendererException { canvas.getTextureManager().draw(this, texture, anchor, position, 0); } @Override public void draw(Texture texture, AnchorPosition anchor, Vector3d position, double rotationAngle) throws SciRendererException { canvas.getTextureManager().draw(this, texture, anchor, position, rotationAngle); } /** * Bind the given texture to the OpenGl context. * @param texture the given texture. * @throws SciRendererException is thrown if the texture is invalid. */ public void bind(Texture texture) throws SciRendererException { canvas.getTextureManager().bind(this, texture); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/JoGLParameters.java000066400000000000000000000033221212506735300317060ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl; import javax.media.opengl.GL; import javax.media.opengl.glu.GLU; /** * @author Pierre Lando */ public class JoGLParameters { private static final boolean USE_DISPLAY_LIST = false; private static final boolean USE_POINT_SPRITE = true; private static Boolean USE_VBO; /** * Default constructor. * It's package : only JoGLCanvas need this kind of object. */ JoGLParameters() { } /** * Use display list. * @return true if use display list. */ public boolean useDisplayList() { return USE_DISPLAY_LIST; } /** * Use VBO. * @return true if use VBO. */ public boolean useVBO() { if (USE_VBO == null) { GL gl = GLU.getCurrentGL(); USE_VBO = gl.isExtensionAvailable("GL_ARB_vertex_buffer_object") && gl.isFunctionAvailable("glBindBufferARB") && gl.isFunctionAvailable("glGenBuffersARB") && gl.isFunctionAvailable("glBufferDataARB") && gl.isFunctionAvailable("glDeleteBuffersARB"); } return USE_VBO; } /** * Use point sprite. * @return true if use point sprite. */ public boolean usePointSprite() { return USE_POINT_SPRITE; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/buffers/000077500000000000000000000000001212506735300276605ustar00rootroot00000000000000JoGLBuffersManager.java000066400000000000000000000155431212506735300340570ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/buffers/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.buffers; import org.scilab.forge.scirenderer.buffers.BuffersManager; import org.scilab.forge.scirenderer.buffers.DataBuffer; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import javax.media.opengl.GL2; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.Stack; /** * @author Pierre Lando */ public final class JoGLBuffersManager implements BuffersManager { /** * Set off current buffers. */ private final Set buffers = new HashSet(); /** * Set of dead buffers. */ private final Stack deadBuffers = new Stack(); /** * Default constructor. */ public JoGLBuffersManager() { } @Override public synchronized ElementsBuffer createElementsBuffer() { JoGLElementsBuffer newBuffer = new JoGLElementsBuffer(); buffers.add(newBuffer); return newBuffer; } @Override public synchronized IndicesBuffer createIndicesBuffer() { JoGLIndicesBuffer newBuffer = new JoGLIndicesBuffer(); buffers.add(newBuffer); return newBuffer; } @Override public synchronized void dispose(DataBuffer buffer) { JoGLDataBuffer localBuffer = getLocalBuffer(buffer); if (localBuffer != null) { buffers.remove(localBuffer); localBuffer.clear(); deadBuffers.push(localBuffer); } } @Override public synchronized void dispose(Collection buffers) { for (DataBuffer buffer : buffers) { dispose(buffer); } } /** * Called when previous OpenGl context is gone. */ public synchronized void glReload() { for (JoGLDataBuffer buffer : buffers) { buffer.reload(); } } /** * Called before rendering for synchronisation. * Clean dead buffers. * @param gl the OpenGl context. */ public synchronized void glSynchronize(GL2 gl) { int[] names = new int[deadBuffers.size()]; int i = 0; while (!deadBuffers.isEmpty()) { int n = deadBuffers.pop().disposeWithoutDelete(gl); if (n != -1) { names[i++] = n; } } if (i != 0) { gl.glDeleteBuffers(i, names, 0); } } /** * Bind the given buffer as vertex buffer. * @param gl the OpenGl context where the buffer is bind. * @param buffer the buffer to bind. * @return the number of element actually bind. */ public int bindVertexBuffer(GL2 gl, ElementsBuffer buffer) { JoGLElementsBuffer localBuffer = getLocalElementsBuffer(buffer); if (localBuffer != null) { return localBuffer.bindAsVertexBuffer(gl); } else { return 0; } } /** * Bind the given buffer as normal buffer. * @param gl the OpenGl context where the buffer is bind. * @param buffer the buffer to bind. * @return the number of element actually bind. */ public int bindNormalsBuffer(GL2 gl, ElementsBuffer buffer) { JoGLElementsBuffer localBuffer = getLocalElementsBuffer(buffer); if (localBuffer != null) { return localBuffer.bindAsNormalsBuffer(gl); } else { return 0; } } /** * Bind the given buffer as texture coordinate buffer. * @param gl the OpenGl context where the buffer is bind. * @param buffer the buffer to bind. * @return the number of element actually bind. */ public int bindTextureCoordinatesBuffer(GL2 gl, ElementsBuffer buffer) { JoGLElementsBuffer localBuffer = getLocalElementsBuffer(buffer); if (localBuffer != null) { return localBuffer.bindAsTextureCoordinatesBuffer(gl); } else { return 0; } } /** * Bind the given buffer as color buffer. * @param gl the OpenGl context where the buffer is bind. * @param buffer the buffer to bind. * @return the number of element actually bind. */ public int bindColorsBuffer(GL2 gl, ElementsBuffer buffer) { JoGLElementsBuffer localBuffer = getLocalElementsBuffer(buffer); if (localBuffer != null) { return localBuffer.bindAsColorsBuffer(gl); } else { return 0; } } /** * Bind the given buffer as indices buffer. * @param gl the OpenGl context where the buffer is bind. * @param buffer the buffer to bind. * @return the number of element actually bind. */ public int bindIndicesBuffer(GL2 gl, IndicesBuffer buffer) { JoGLDataBuffer localBuffer = getLocalBuffer(buffer); if (localBuffer != null) { gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, localBuffer.getGlName(gl)); return buffer.getSize(); } else { return 0; } } /** * This method check buffer to be from here. * @param buffer the given buffer. * @return the JoGL instance of the buffer. */ private synchronized JoGLDataBuffer getLocalBuffer(DataBuffer buffer) { if (buffer instanceof JoGLDataBuffer) { JoGLDataBuffer localBuffer = (JoGLDataBuffer) buffer; if (buffers.contains(localBuffer)) { return localBuffer; } } return null; } /** * This method check buffer to be from here. * @param buffer the given buffer. * @return the JoGL instance of the buffer. */ private synchronized JoGLIndicesBuffer getLocalIndicesBuffer(IndicesBuffer buffer) { if (buffer instanceof JoGLIndicesBuffer) { JoGLIndicesBuffer localBuffer = (JoGLIndicesBuffer) buffer; if (buffers.contains(localBuffer)) { return localBuffer; } } return null; } /** * This method check buffer to be from here. * @param buffer the given buffer. * @return the JoGL instance of the buffer. */ private synchronized JoGLElementsBuffer getLocalElementsBuffer(ElementsBuffer buffer) { if (buffer instanceof JoGLElementsBuffer) { JoGLElementsBuffer localBuffer = (JoGLElementsBuffer) buffer; if (buffers.contains(localBuffer)) { return localBuffer; } } return null; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/buffers/JoGLDataBuffer.java000066400000000000000000000075611212506735300332530ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.buffers; import org.scilab.forge.scirenderer.buffers.DataBuffer; import javax.media.opengl.GL; import java.nio.Buffer; /** * @author Pierre Lando */ public abstract class JoGLDataBuffer implements DataBuffer { /** * True if the data have been uploaded to OpenGl driver. */ private boolean dataUploaded; /** * The OpenGl name for this buffer. * - null : no name * - an Integer : the name. */ private Integer glName; /** * Default constructor. * The constructor is package : only {@link JoGLBuffersManager} can instantiate this object. */ JoGLDataBuffer() { dataUploaded = false; glName = null; } /** * Called to reload a buffer. */ public void reload() { glName = null; dataUploaded = false; } /** * Called when it's time to kill this buffer. * @param gl the OpenGl context. */ public void dispose(GL gl) { if ((glName != null) && gl.glIsBuffer(glName)) { int[] t = new int[]{glName}; gl.glDeleteBuffers(1, t, 0); glName = null; dataUploaded = false; } } /** * Called when it's time to kill this buffer. * The effective delete is done in JoGLBuffersManager::glSynchronize (to vectorize it). * @param gl the OpenGl context. */ public int disposeWithoutDelete(GL gl) { if ((glName != null) && gl.glIsBuffer(glName)) { int n = glName; glName = null; dataUploaded = false; return n; } return -1; } /** * Synchronize this buffer. * @param gl the OpenGl context where synchronization is done. */ protected void synchronize(GL gl) { // Check the glName. if ((glName == null) || !(gl.glIsBuffer(glName))) { int[] t = new int[1]; gl.glGenBuffers(1, t, 0); glName = t[0]; dataUploaded = false; } // Upload data to the OpenGl driver. if (!dataUploaded) { gl.glBindBuffer(getGLBindDestination(), glName); gl.glBufferData(getGLBindDestination(), getByteSize(), getByteBuffer(), GL.GL_STATIC_DRAW); gl.glBindBuffer(getGLBindDestination(), 0); dataUploaded = true; } } /** * Return the data uploaded status. * @return the data uploaded status. */ protected boolean isDataUploaded() { return dataUploaded; } /** * Set the data uploaded status. * @param dataUploaded the new data uploaded status. */ protected void setDataUploaded(boolean dataUploaded) { this.dataUploaded = dataUploaded; } /** * Return the OpenGl name of this buffer. * @param gl the OpenGl context. * @return the OpenGl name of this buffer. */ protected Integer getGlName(GL gl) { synchronize(gl); return glName; } /** * Return the data as byte buffer. * @return the data as byte buffer. */ protected abstract Buffer getByteBuffer(); /** * Return the OpenGl bind destination. * @return the OpenGl bind destination. */ protected abstract int getGLBindDestination(); /** * Return the size of this buffer in byte. * @return the size of this buffer in byte. */ public abstract int getByteSize(); public abstract void clear(); } JoGLElementsBuffer.java000066400000000000000000000221771212506735300340770ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/buffers/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.buffers; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import javax.media.opengl.GL2; import java.nio.Buffer; import java.nio.FloatBuffer; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public class JoGLElementsBuffer extends JoGLDataBuffer implements ElementsBuffer { /** * The current size of one element. */ public static final int ELEMENT_SIZE = 4; /** * The default vertex. */ private static final float[] DEFAULT_VERTEX = new float[] {0, 0, 0, 1}; /** * the data this buffer contain. */ private FloatBuffer data; private final Object mutex; /** * Default constructor. * The constructor is package : only {@link JoGLBuffersManager} can instantiate this object. */ JoGLElementsBuffer() { mutex = new Object(); data = null; } @Override public void setData(float[] newData, int elementSize) { // Check the given vertex size if ((elementSize < 1) || (elementSize > ELEMENT_SIZE)) { throw new BadElementSizeException(elementSize, 1, ELEMENT_SIZE); } int verticesNumber = newData.length / elementSize; //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber); FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber); buffer.rewind(); // Fill buffer with given data. // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones. int k = 0; for (int i = 0; i < verticesNumber; i++) { for (int j = 0; j < ELEMENT_SIZE; j++) { if (j < elementSize) { buffer.put(newData[k++]); } else { buffer.put(DEFAULT_VERTEX[j]); } } } buffer.rewind(); setData(buffer); setDataUploaded(false); } @Override public void setData(Float[] newData, int elementSize) { // Check the given vertex size if ((elementSize < 1) || (elementSize > ELEMENT_SIZE)) { throw new BadElementSizeException(elementSize, 1, ELEMENT_SIZE); } int verticesNumber = newData.length / elementSize; //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber); FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber); buffer.rewind(); // Fill buffer with given data. // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones. int k = 0; for (int i = 0; i < verticesNumber; i++) { for (int j = 0; j < ELEMENT_SIZE; j++) { if (j < elementSize) { buffer.put(newData[k++]); } else { buffer.put(DEFAULT_VERTEX[j]); } } } buffer.rewind(); setData(buffer); setDataUploaded(false); } @Override public void setData(FloatBuffer newData, int elementsSize) { // Check the given vertex size if ((elementsSize < 1) || (elementsSize > ELEMENT_SIZE)) { throw new BadElementSizeException(elementsSize, 1, ELEMENT_SIZE); } if (elementsSize == 4) { // No need to complete buffer. if (newData != null) { newData.rewind(); } setData(newData); setDataUploaded(false); return; } int verticesNumber = newData.limit() / elementsSize; //FloatBuffer buffer = BufferUtil.newFloatBuffer(ELEMENT_SIZE * verticesNumber); FloatBuffer buffer = FloatBuffer.allocate(ELEMENT_SIZE * verticesNumber); buffer.rewind(); // Fill buffer with given data. // Missing coordinate are filled with the 'DEFAULT_VERTEX' ones. newData.rewind(); for (int i = 0; i < verticesNumber; i++) { for (int j = 0; j < ELEMENT_SIZE; j++) { if (j < elementsSize) { buffer.put(newData.get()); } else { buffer.put(DEFAULT_VERTEX[j]); } } } buffer.rewind(); setData(buffer); setDataUploaded(false); } @Override public int getSize() { synchronized (mutex) { if (data == null) { return 0; } else { return data.limit() / ELEMENT_SIZE; } } } @Override public FloatBuffer getData() { synchronized (mutex) { if (data != null) { return data; } else { return null; } } } @Override public int getElementsSize() { return ELEMENT_SIZE; } @Override public int getByteSize() { synchronized (mutex) { if (data == null) { return 0; } else { return data.limit() * (Float.SIZE / Byte.SIZE); } } } @Override protected Buffer getByteBuffer() { synchronized (mutex) { if (data != null) { data.rewind(); } return data; } } @Override protected int getGLBindDestination() { return GL2.GL_ARRAY_BUFFER; } public int bindAsVertexBuffer(GL2 gl) { synchronized (mutex) { if (getSize() != 0) { gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, getGlName(gl)); gl.glVertexPointer(getElementsSize(), GL2.GL_FLOAT, 0, 0); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); if (data == null) { return 0; } else { return data.limit() * (Float.SIZE / Byte.SIZE); } } else { return 0; } } } public int bindAsNormalsBuffer(GL2 gl) { synchronized (mutex) { if (getSize() != 0) { gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, getGlName(gl)); gl.glNormalPointer(GL2.GL_FLOAT, getElementsSize() * Float.SIZE / Byte.SIZE, 0); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); if (data == null) { return 0; } else { return data.limit() * (Float.SIZE / Byte.SIZE); } } else { return 0; } } } public int bindAsColorsBuffer(GL2 gl) { synchronized (mutex) { if (getSize() != 0) { gl.glEnableClientState(GL2.GL_COLOR_ARRAY); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, getGlName(gl)); gl.glColorPointer(getElementsSize(), GL2.GL_FLOAT, 0, 0); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); if (data == null) { return 0; } else { return data.limit() * (Float.SIZE / Byte.SIZE); } } else { return 0; } } } public int bindAsTextureCoordinatesBuffer(GL2 gl) { synchronized (mutex) { if (getSize() != 0) { gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, getGlName(gl)); gl.glTexCoordPointer(getElementsSize(), GL2.GL_FLOAT, 0, 0); gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0); if (data == null) { return 0; } else { return data.limit() * (Float.SIZE / Byte.SIZE); } } else { return 0; } } } /** * Really set the data. * @param data the new data. */ private void setData(FloatBuffer data) { synchronized (mutex) { this.data = data; } } /** * A specific runtime exception for bad elements size. */ private static class BadElementSizeException extends RuntimeException { /** * Default constructor. * @param size the size given for elements. * @param min the minimum possible size. * @param max the upper bound of possible size (excluded of possible size). */ public BadElementSizeException(int size, int min, int max) { super("Bad vertex elements size : " + size + ". Should be in [" + min + ", " + (max - 1) + "]"); } } @Override public void clear() { if (data != null) { data.clear(); } data = null; } } JoGLIndicesBuffer.java000066400000000000000000000055211212506735300336730ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/buffers/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.buffers; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import javax.media.opengl.GL; import java.nio.Buffer; import java.nio.IntBuffer; import java.util.Collection; /** * @author Pierre Lando */ public class JoGLIndicesBuffer extends JoGLDataBuffer implements IndicesBuffer { /** * the data this buffer contain. */ private IntBuffer data; /** * Default constructor. * The constructor is package : only {@link JoGLBuffersManager} can instantiate this object. */ JoGLIndicesBuffer() { data = null; } @Override public void setData(int[] indices) { //IntBuffer buffer = BufferUtil.newIntBuffer(indices.length); IntBuffer buffer = IntBuffer.allocate(indices.length); buffer.rewind(); buffer.put(indices); buffer.rewind(); this.data = buffer; setDataUploaded(false); } @Override public void setData(Collection indices) { IntBuffer buffer = IntBuffer.allocate(indices.size()); buffer.rewind(); for (int index : indices) { buffer.put(index); } buffer.rewind(); this.data = buffer; setDataUploaded(false); } @Override public void setData(IntBuffer indexBuffer) { //IntBuffer buffer = BufferUtil.newIntBuffer(indexBuffer.limit()); IntBuffer buffer = IntBuffer.allocate(indexBuffer.limit()); buffer.rewind(); indexBuffer.rewind(); buffer.put(indexBuffer); buffer.rewind(); indexBuffer.rewind(); this.data = buffer; setDataUploaded(false); } @Override public int getSize() { if (data == null) { return 0; } else { return data.limit(); } } @Override public IntBuffer getData() { return data.asReadOnlyBuffer(); } @Override public int getByteSize() { if (data == null) { return 0; } else { return data.limit() * (Integer.SIZE / Byte.SIZE); } } @Override protected Buffer getByteBuffer() { if (data != null) { data.rewind(); } return data; } @Override protected int getGLBindDestination() { return GL.GL_ELEMENT_ARRAY_BUFFER; } public void clear() { data.clear(); data = null; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/clipping/000077500000000000000000000000001212506735300300315ustar00rootroot00000000000000JoGLClippingManager.java000066400000000000000000000043411212506735300343730ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/clipping/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.clipping; import org.scilab.forge.scirenderer.clipping.ClippingManager; import org.scilab.forge.scirenderer.clipping.ClippingPlane; import org.scilab.forge.scirenderer.implementation.jogl.JoGLDrawingTools; import javax.media.opengl.GL2; /** * @author Pierre Lando */ public class JoGLClippingManager implements ClippingManager { /** * Used drawing tools. */ private final JoGLDrawingTools drawingTools; /** * Clipping planes array. */ private final JoGLClippingPlane[] clippingPlanes; /** * Default constructor. * @param drawingTools used drawing tools. */ public JoGLClippingManager(JoGLDrawingTools drawingTools) { this.drawingTools = drawingTools; this.clippingPlanes = new JoGLClippingPlane[getClippingPlaneNumber()]; } @Override public int getClippingPlaneNumber() { return drawingTools.getGLCapacity().getClippingPlaneNumber(); } @Override public JoGLClippingPlane getClippingPlane(int i) { if (i < 0 || i >= getClippingPlaneNumber()) { return null; } else { if (clippingPlanes[i] == null) { clippingPlanes[i] = new JoGLClippingPlane(drawingTools.getGl().getGL2(), i); } return clippingPlanes[i]; } } @Override public void disableClipping() { for (ClippingPlane clippingPlane : clippingPlanes) { if (clippingPlane != null) { clippingPlane.setEnable(false); } } } public void reload() { GL2 gl = drawingTools.getGl().getGL2(); for (JoGLClippingPlane clippingPlane : clippingPlanes) { if (clippingPlane != null) { clippingPlane.reload(gl); } } } } JoGLClippingPlane.java000066400000000000000000000062711212506735300340640ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/clipping/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.clipping; import org.scilab.forge.scirenderer.clipping.ClippingPlane; import org.scilab.forge.scirenderer.implementation.jogl.utils.GLShortCuts; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationFactory; import org.scilab.forge.scirenderer.tranformations.Vector4d; import javax.media.opengl.GL2; /** * @author Pierre Lando */ public class JoGLClippingPlane implements ClippingPlane { /** * GL index of this clipping plane. */ private final int index; /** * Current GL context. */ private GL2 gl; /** * Clipping plane enabled status. */ private boolean isEnable; /** * Clipping plane equation look like: {@code x*a + y*b + z*c + d = 0}. * Where {@code equation} is {@code [a, b, c, d]}. */ private Vector4d equation = new Vector4d(0, 0, 0, 0); private Transformation transformation = TransformationFactory.getIdentity(); /** * Default constructor. * @param gl the OpenGl context. * @param index the id of this clipping plane. */ public JoGLClippingPlane(GL2 gl, int index) { this.isEnable = false; this.index = index; reload(gl); } @Override public boolean isEnable() { return isEnable; } @Override public void setEnable(boolean isEnable) { this.isEnable = isEnable; GLShortCuts.setEnable(gl, GL2.GL_CLIP_PLANE0 + getIndex(), isEnable); } @Override public void setEquation(Vector4d v) { equation = v; setGLEquation(); } @Override public Vector4d getEquation() { return equation; } @Override public void setTransformation(Transformation transformation) { this.transformation = transformation; setGLEquation(); } @Override public Transformation getTransformation() { return transformation; } @Override public int getIndex() { return index; } /** * Set GL context and synchronise it. * @param gl the current gl context. */ void reload(GL2 gl) { this.gl = gl; GLShortCuts.setEnable(gl, GL2.GL_CLIP_PLANE0 + getIndex(), isEnable()); setGLEquation(); } /** * Set the GL equation. */ private void setGLEquation() { // We use global coordinate. So we need to load identity. gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glPushMatrix(); if (transformation == null) { gl.glLoadIdentity(); } else { gl.glLoadMatrixd(transformation.getMatrix(), 0); } gl.glClipPlane(GL2.GL_CLIP_PLANE0 + getIndex(), equation.getData(), 0); gl.glPopMatrix(); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/drawer/000077500000000000000000000000001212506735300275105ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/drawer/JoGLShapeDrawer.java000066400000000000000000000357311212506735300333050ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.drawer; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import org.scilab.forge.scirenderer.implementation.jogl.JoGLDrawingTools; import org.scilab.forge.scirenderer.implementation.jogl.buffers.JoGLBuffersManager; import org.scilab.forge.scirenderer.implementation.jogl.buffers.JoGLElementsBuffer; import org.scilab.forge.scirenderer.implementation.jogl.utils.GLShortCuts; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.Texture; import javax.media.opengl.GL2; import java.nio.FloatBuffer; import java.nio.IntBuffer; /** * Utility class for drawing shapes. * @author Pierre Lando */ public final class JoGLShapeDrawer { private static JoGLShapeDrawer drawer; /** * Private constructor : this is an utility class. */ private JoGLShapeDrawer() { } /** * Singleton getter. * @return the unique {@link JoGLShapeDrawer}. */ public static JoGLShapeDrawer getDrawer() { if (drawer == null) { drawer = new JoGLShapeDrawer(); } return drawer; } /** * Draw a given geometry with given appearance. * @param drawingTools the drawing tools. * @param geometry the geometry. * @param appearance the appearance. * @throws org.scilab.forge.scirenderer.SciRendererException if the draw is not possible. */ public void draw(JoGLDrawingTools drawingTools, Geometry geometry, Appearance appearance) throws SciRendererException { GL2 gl = drawingTools.getGl().getGL2(); gl.glFrontFace(GL2.GL_CCW); switch (geometry.getFaceCullingMode()) { case CW: gl.glEnable(GL2.GL_CULL_FACE); gl.glCullFace(GL2.GL_FRONT); break; case CCW: gl.glEnable(GL2.GL_CULL_FACE); gl.glCullFace(GL2.GL_BACK); break; case BOTH: gl.glDisable(GL2.GL_CULL_FACE); break; default: gl.glDisable(GL2.GL_CULL_FACE); break; } if (drawingTools.getCanvas().getJoGLParameters().useVBO()) { vboDrawing(drawingTools, geometry, appearance); } else { directDrawing(drawingTools, geometry, appearance); } GLShortCuts.useLineAppearance(gl, null); gl.glDisable(GL2.GL_CULL_FACE); } /** * Perform geometry drawing using VBO. * @param drawingTools the drawing tools. * @param geometry the geometry to draw. * @param appearance the current appearance. * @throws org.scilab.forge.scirenderer.SciRendererException if the draw is not possible. */ private void vboDrawing(JoGLDrawingTools drawingTools, Geometry geometry, Appearance appearance) throws SciRendererException { final GL2 gl = drawingTools.getGl().getGL2(); final JoGLBuffersManager buffersManager = drawingTools.getCanvas().getBuffersManager(); final Texture texture = appearance.getTexture(); int verticesNumber = buffersManager.bindVertexBuffer(gl, geometry.getVertices()); if (verticesNumber == 0) { gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); return; } buffersManager.bindNormalsBuffer(gl, geometry.getNormals()); if (texture != null && geometry.getTextureCoordinates() != null) { synchronized (texture) { if (texture.isValid()) { drawingTools.bind(texture); buffersManager.bindTextureCoordinatesBuffer(gl, geometry.getTextureCoordinates()); } } } else { buffersManager.bindColorsBuffer(gl, geometry.getColors()); } // We use polygon offset for filled geometry if required. if (geometry.getPolygonOffsetMode()) { gl.glEnable(GL2.GL_POLYGON_OFFSET_FILL); gl.glPolygonOffset(1, 1); } GLShortCuts.useColor(gl, appearance.getFillColor()); IndicesBuffer indices = geometry.getIndices(); if (geometry.getFillDrawingMode() != Geometry.FillDrawingMode.NONE) { if (indices != null) { int indicesSize = buffersManager.bindIndicesBuffer(gl, indices); if (indicesSize > 0) { gl.glDrawElements(getGlMode(geometry.getFillDrawingMode()), indicesSize, GL2.GL_UNSIGNED_INT, 0); gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0); } } else { int count = geometry.getVertices().getSize(); if (count > 0) { gl.glDrawArrays(getGlMode(geometry.getFillDrawingMode()), 0, count); } } } if (geometry.getPolygonOffsetMode()) { gl.glDisable(GL2.GL_POLYGON_OFFSET_FILL); } gl.glDisableClientState(GL2.GL_COLOR_ARRAY); gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY); gl.glDisable(GL2.GL_TEXTURE_2D); if (geometry.getLineDrawingMode() != Geometry.LineDrawingMode.NONE) { if (appearance.getLineColor() != null || geometry.getColors() != null) { GLShortCuts.useLineAppearance(gl, appearance); if (appearance.getLineColor() == null) { buffersManager.bindColorsBuffer(gl, geometry.getColors()); } if (geometry.getWireIndices() != null) { int edgesIndicesSize = buffersManager.bindIndicesBuffer(gl, geometry.getWireIndices()); if (edgesIndicesSize > 0) { gl.glDrawElements(getGlMode(geometry.getLineDrawingMode()), edgesIndicesSize, GL2.GL_UNSIGNED_INT, 0); gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0); } } else { int count = geometry.getVertices().getSize(); if (count > 0) { gl.glDrawArrays(getGlMode(geometry.getLineDrawingMode()), 0, count); } } gl.glDisableClientState(GL2.GL_COLOR_ARRAY); } } gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); } /** * Perform geometry drawing by direct OpenGl call. * @param drawingTools the drawing tools. * @param geometry the geometry to draw. * @param appearance the used appearance. * @throws org.scilab.forge.scirenderer.SciRendererException if the draw is not possible. */ private void directDrawing( JoGLDrawingTools drawingTools, Geometry geometry, Appearance appearance ) throws SciRendererException { final double sfactor; final double tfactor; final float[] fbuffer = new float[4]; GL2 gl = drawingTools.getGl().getGL2(); if (geometry.getVertices() == null) { return; } FloatBuffer vertexBuffer = geometry.getVertices().getData(); IndicesBuffer indices = geometry.getIndices(); FloatBuffer colorBuffer; if (geometry.getColors() != null) { colorBuffer = geometry.getColors().getData(); } else { colorBuffer = null; } FloatBuffer normalBuffer; if (geometry.getNormals() != null) { normalBuffer = geometry.getNormals().getData(); } else { normalBuffer = null; } Texture texture = appearance.getTexture(); FloatBuffer textureCoordinatesBuffer; if (texture != null && geometry.getTextureCoordinates() != null) { synchronized (texture) { drawingTools.bind(texture); textureCoordinatesBuffer = geometry.getTextureCoordinates().getData(); sfactor = texture.getSScaleFactor(); tfactor = texture.getTScaleFactor(); } } else { textureCoordinatesBuffer = null; sfactor = 1; tfactor = 1; } final int elementsSize = JoGLElementsBuffer.ELEMENT_SIZE; if (geometry.getPolygonOffsetMode()) { gl.glEnable(GL2.GL_POLYGON_OFFSET_FILL); gl.glPolygonOffset(1, 1); } if (geometry.getFillDrawingMode() != Geometry.FillDrawingMode.NONE) { GLShortCuts.useColor(gl, appearance.getFillColor()); gl.glBegin(getGlMode(geometry.getFillDrawingMode())); if (indices != null) { IntBuffer indicesBuffer = indices.getData(); indicesBuffer.rewind(); for (int i = 0; i < indicesBuffer.limit(); i++) { int index = indicesBuffer.get(i); if ((index * elementsSize) < vertexBuffer.limit()) { if (colorBuffer != null) { colorBuffer.position(index * elementsSize); gl.glColor4fv(colorBuffer); } if (normalBuffer != null) { normalBuffer.position(index * elementsSize); gl.glNormal3fv(normalBuffer); } if (textureCoordinatesBuffer != null) { textureCoordinatesBuffer.position(index * elementsSize); textureCoordinatesBuffer.get(fbuffer); gl.glTexCoord4f((float) (sfactor * fbuffer[0]), (float) (tfactor * fbuffer[1]), fbuffer[2], fbuffer[3]); } vertexBuffer.position(index * elementsSize); gl.glVertex4fv(vertexBuffer); } } } else { vertexBuffer.rewind(); if (colorBuffer != null) { colorBuffer.rewind(); } if (normalBuffer != null) { normalBuffer.rewind(); } for (int i = 0; i < vertexBuffer.limit(); i += elementsSize) { if (colorBuffer != null) { colorBuffer.position(i); gl.glColor4fv(colorBuffer); } if (normalBuffer != null) { normalBuffer.position(i); gl.glNormal3fv(normalBuffer); } if (textureCoordinatesBuffer != null) { textureCoordinatesBuffer.position(i); gl.glTexCoord4fv(textureCoordinatesBuffer); } vertexBuffer.position(i); gl.glVertex4fv(vertexBuffer); } } gl.glEnd(); } if (geometry.getPolygonOffsetMode()) { gl.glDisable(GL2.GL_POLYGON_OFFSET_FILL); } gl.glDisable(GL2.GL_TEXTURE_2D); // Draw edges if any. if (geometry.getLineDrawingMode() != Geometry.LineDrawingMode.NONE) { GLShortCuts.useLineAppearance(gl, appearance); if (appearance.getLineColor() != null) { gl.glBegin(getGlMode(geometry.getLineDrawingMode())); if (geometry.getWireIndices() != null) { IntBuffer edgesIndicesBuffer = geometry.getWireIndices().getData(); edgesIndicesBuffer.rewind(); while (edgesIndicesBuffer.remaining() != 0) { int index = edgesIndicesBuffer.get(); if ((index * elementsSize) < vertexBuffer.limit()) { vertexBuffer.position(index * elementsSize); gl.glVertex4fv(vertexBuffer); } } } else { for (int i = 0; i < vertexBuffer.limit(); i += elementsSize) { vertexBuffer.position(i); gl.glVertex4fv(vertexBuffer); } } gl.glEnd(); } else if (colorBuffer != null) { gl.glBegin(getGlMode(geometry.getLineDrawingMode())); if (geometry.getWireIndices() != null) { IntBuffer edgesIndicesBuffer = geometry.getWireIndices().getData(); edgesIndicesBuffer.rewind(); while (edgesIndicesBuffer.remaining() != 0) { int index = edgesIndicesBuffer.get(); if ((index * elementsSize) < vertexBuffer.limit()) { colorBuffer.position(index * elementsSize); gl.glColor4fv(colorBuffer); vertexBuffer.position(index * elementsSize); gl.glVertex4fv(vertexBuffer); } } } else { for (int i = 0; i < vertexBuffer.limit(); i += elementsSize) { colorBuffer.position(i); vertexBuffer.position(i); gl.glColor4fv(colorBuffer); gl.glVertex4fv(vertexBuffer); } } gl.glEnd(); } } } /** * Return the gl drawing mode corresponding to the given {@link Geometry.FillDrawingMode}. * @param drawingMode the given drawing mode.. * @return the gl drawing mode corresponding to the given {@link Geometry.FillDrawingMode}. */ private int getGlMode(Geometry.FillDrawingMode drawingMode) { switch (drawingMode) { case TRIANGLE_FAN: return GL2.GL_TRIANGLE_FAN; case TRIANGLE_STRIP: return GL2.GL_TRIANGLE_STRIP; case TRIANGLES: return GL2.GL_TRIANGLES; default: return GL2.GL_TRIANGLES; } } /** * Return the gl drawing mode corresponding to the given {@link org.scilab.forge.scirenderer.shapes.geometry.Geometry.LineDrawingMode} * @param drawingMode the given drawing mode. * @return the gl drawing mode corresponding to the given {@link org.scilab.forge.scirenderer.shapes.geometry.Geometry.LineDrawingMode} */ private int getGlMode(Geometry.LineDrawingMode drawingMode) { switch (drawingMode) { case SEGMENTS: return GL2.GL_LINES; case SEGMENTS_LOOP: return GL2.GL_LINE_LOOP; case SEGMENTS_STRIP: return GL2.GL_LINE_STRIP; default: return GL2.GL_LINES; } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/lightning/000077500000000000000000000000001212506735300302075ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/lightning/JoGLLight.java000066400000000000000000000107161212506735300326420ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.lightning; import javax.media.opengl.GL2; import org.scilab.forge.scirenderer.implementation.jogl.utils.GLShortCuts; import org.scilab.forge.scirenderer.lightning.Light; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Pierre Lando */ public class JoGLLight implements Light { private final int index; private GL2 gl; private boolean isEnable; private Color ambientColor = new Color(0, 0, 0); private Color diffuseColor = new Color(0, 0, 0); private Color specularColor = new Color(0, 0, 0); private Vector3d position = new Vector3d(0, 0, 0); private Vector3d spotDirection = new Vector3d(0, 0, -1); private float spotAngle = 180; /** * Default constructor. * @param gl the gl context. * @param index the light index. */ public JoGLLight(GL2 gl, int index) { this.gl = gl; this.index = index; } /** * Reload this light. * @param gl the gl context. */ public void reload(GL2 gl) { this.gl = gl; GLShortCuts.setEnable(gl, GL2.GL_LIGHT0 + index, isEnable); gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_AMBIENT, ambientColor.getRGBComponents(null), 0); gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_DIFFUSE, diffuseColor.getRGBComponents(null), 0); gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_SPECULAR, specularColor.getRGBComponents(null), 0); gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_POSITION, position.getDataAsFloatArray(4), 0); gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_SPOT_DIRECTION, spotDirection.getDataAsFloatArray(4), 0); } @Override public boolean isEnable() { return isEnable; } @Override public void setEnable(boolean enable) { if (enable != isEnable) { isEnable = enable; GLShortCuts.setEnable(gl, GL2.GL_LIGHT0 + index, isEnable); } } @Override public Color getAmbientColor() { return ambientColor; } @Override public void setAmbientColor(Color color) { if (color != null) { ambientColor = color; gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_AMBIENT, ambientColor.getRGBComponents(null), 0); } } @Override public Color getDiffuseColor() { return diffuseColor; } @Override public void setDiffuseColor(Color color) { if (color != null) { diffuseColor = color; gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_DIFFUSE, diffuseColor.getRGBComponents(null), 0); } } @Override public Color getSpecularColor() { return specularColor; } @Override public void setSpecularColor(Color color) { if (color != null) { specularColor = color; gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_SPECULAR, specularColor.getRGBComponents(null), 0); } } @Override public Vector3d getPosition() { return position; } @Override public void setPosition(Vector3d position) { if (position != null) { this.position = position; gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_POSITION, position.getDataAsFloatArray(4), 0); } } @Override public Vector3d getSpotDirection() { return spotDirection; } @Override public void setSpotDirection(Vector3d spotDirection) { if (spotDirection != null) { this.spotDirection = spotDirection; gl.glLightfv(GL2.GL_LIGHT0 + index, GL2.GL_SPOT_DIRECTION, spotDirection.getNormalized().getDataAsFloatArray(4), 0); } } @Override public float getSpotAngle() { return spotAngle; } @Override public void setSpotAngle(float angle) { if (angle != spotAngle) { spotAngle = angle; gl.glLightf(GL2.GL_LIGHT0 + index, GL2.GL_SPOT_CUTOFF, spotAngle); } } @Override public int getIndex() { return index; } } JoGLLightManager.java000066400000000000000000000047361212506735300340630ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/lightning/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.lightning; import org.scilab.forge.scirenderer.implementation.jogl.JoGLDrawingTools; import org.scilab.forge.scirenderer.implementation.jogl.utils.GLShortCuts; import org.scilab.forge.scirenderer.lightning.Light; import org.scilab.forge.scirenderer.lightning.LightManager; import javax.media.opengl.GL2; /** * JoGL implementation of {@link LightManager} * * @author Pierre Lando */ public class JoGLLightManager implements LightManager { /** * The drawing tools. */ private final JoGLDrawingTools drawingTools; /** * The lights. */ private final JoGLLight[] lights; /** * The current lightning status. */ private boolean isLightningEnable = DEFAULT_LIGHTNING_STATUS; /** * Default constructor. * @param drawingTools the drawing tools. */ public JoGLLightManager(JoGLDrawingTools drawingTools) { this.drawingTools = drawingTools; lights = new JoGLLight[getLightNumber()]; } @Override public int getLightNumber() { return drawingTools.getGLCapacity().getLightNumber(); } @Override public Light getLight(int i) { if (i < 0 || i >= getLightNumber()) { return null; } else { if (lights[i] == null) { lights[i] = new JoGLLight(drawingTools.getGl(), i); } return lights[i]; } } @Override public void setLightningEnable(boolean isLightningEnable) { this.isLightningEnable = isLightningEnable; GLShortCuts.setEnable(drawingTools.getGl().getGL2(), GL2.GL_LIGHTING, isLightningEnable); } @Override public boolean isLightningEnable() { return isLightningEnable; } /** * Reload light. */ public void reload() { GL2 gl = drawingTools.getGl().getGL2(); GLShortCuts.setEnable(gl, GL2.GL_LIGHTING, isLightningEnable); for (JoGLLight light : lights) { if (light != null) { light.reload(gl); } } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/picking/000077500000000000000000000000001212506735300276505ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/picking/GLPickingManager.java000066400000000000000000000046001212506735300336150ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.picking; import javax.media.opengl.GL; /** * @author Pierre Lando */ public class GLPickingManager { /** * The last used unique color. */ private UniqueColor uniqueColor; /** * Default constructor. */ public GLPickingManager() { } /** * This class make an unique color from an index. */ private class UniqueColor { private final int redSize; private final int greenSize; private final int blueSize; private final GL gl; /** * Constructor. * @param gl the used OpenGl context. */ public UniqueColor(GL gl) { this.gl = gl; int[] colorBits = new int[3]; gl.glGetIntegerv(GL.GL_RED_BITS, colorBits, 0); gl.glGetIntegerv(GL.GL_GREEN_BITS, colorBits, 1); gl.glGetIntegerv(GL.GL_BLUE_BITS, colorBits, 2); redSize = 1 << colorBits[0]; greenSize = 1 << colorBits[1]; blueSize = 1 << colorBits[2]; } /** * Set the color by index. * @param index given index. */ public void setColor(int index) { int i = index; float b = (i % blueSize) / (blueSize - 1f); i = i >> blueSize; float g = (i % greenSize) / (greenSize - 1f); i = i >> greenSize; float r = (i % redSize) / (redSize - 1f); //gl.glColor3f(r, g, b); gl.glClearColor(r, g, b, 0); } /** * Get index from color. * @param r red component of the color. * @param g green component of the color. * @param b blue component of the color. * @return the index corresponding to the given color. */ public int getIndex(float r, float g, float b) { return (int) (((r * (redSize - 1f) + g) * (greenSize - 1f) + b) * (blueSize - 1f)); } } } JoGLPickingManager.java000066400000000000000000000034221212506735300340300ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/picking/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.picking; import org.scilab.forge.scirenderer.implementation.jogl.JoGLCanvas; import org.scilab.forge.scirenderer.implementation.jogl.JoGLDrawingTools; import org.scilab.forge.scirenderer.picking.PickingManager; import org.scilab.forge.scirenderer.picking.PickingTask; import org.scilab.forge.scirenderer.picking.PickingTools; import java.util.Stack; /** * * JoGL implementation of {@link org.scilab.forge.scirenderer.picking.PickingManager} * * @author Pierre Lando */ public class JoGLPickingManager implements PickingManager { private final Stack stack = new Stack(); private final JoGLCanvas canvas; /** * Default constructor. * @param canvas the canvas where picking is performed. */ public JoGLPickingManager(JoGLCanvas canvas) { this.canvas = canvas; } @Override public void addPickingTask(PickingTask pickingTask) { stack.push(pickingTask); canvas.redraw(); } /** * Ask to consume picking task with the given drawing tools. * @param drawingTools the given drawing tools. */ public void glConsume(JoGLDrawingTools drawingTools) { PickingTools pickingTools = new JoGLPickingTools(drawingTools); while (!stack.isEmpty()) { stack.pop().perform(pickingTools); } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/picking/JoGLPickingTools.java000066400000000000000000000036431212506735300336420ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.picking; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.implementation.jogl.JoGLDrawingTools; import org.scilab.forge.scirenderer.picking.PickingTools; import org.scilab.forge.scirenderer.tranformations.Vector3d; import javax.media.opengl.GL2; import java.awt.Point; import java.nio.FloatBuffer; /** * * JoGL implementation of {@link PickingTools} * * @author Pierre Lando */ public class JoGLPickingTools implements PickingTools { private final JoGLDrawingTools drawingTools; /** * Default constructor. * @param drawingTools the drawing tools to use. */ public JoGLPickingTools(JoGLDrawingTools drawingTools) { this.drawingTools = drawingTools; } @Override public Vector3d getUnderlyingPoint(Point windowPosition) { GL2 gl = drawingTools.getGl().getGL2(); int x = windowPosition.x; int y = drawingTools.getCanvas().getHeight() - windowPosition.y - 1; FloatBuffer buffer = FloatBuffer.allocate(1); buffer.rewind(); gl.glReadPixels(x, y, 1, 1, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, buffer); buffer.rewind(); float vz = 2f * buffer.get() - 1; float vx = 2f * x / drawingTools.getCanvas().getWidth() - 1f; float vy = 2f * y / drawingTools.getCanvas().getHeight() - 1f; return new Vector3d(vx, vy, vz); } @Override public Canvas getCanvas() { return drawingTools.getCanvas(); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/renderer/000077500000000000000000000000001212506735300300325ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/renderer/JoGLRenderer.java000066400000000000000000000056321212506735300331650ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.renderer; import org.scilab.forge.scirenderer.Drawer; import org.scilab.forge.scirenderer.implementation.jogl.JoGLDrawingTools; import org.scilab.forge.scirenderer.renderer.Renderer; import javax.media.opengl.GL2; /** * @author Pierre Lando */ public class JoGLRenderer implements Renderer { /** * The current drawer. */ private Drawer drawer; /** * The OpenGl display list name. */ private Integer glName; /** * Store the display list up to date status. */ private boolean upToDate; /** * Default constructor. * The constructor is package : only {@link JoGLRendererManager} can instantiate this object. */ JoGLRenderer() { upToDate = false; drawer = null; glName = null; } @Override public void setDrawer(Drawer drawer) { this.drawer = drawer; upToDate = false; } @Override public Drawer getDrawer() { return drawer; } @Override public void reload() { glName = null; upToDate = false; } /** * Perform a draw to the given canvas. * @param drawingTools the given drawing tools. */ public void draw(JoGLDrawingTools drawingTools) { if (drawingTools.getCanvas().getJoGLParameters().useDisplayList()) { synchronize(drawingTools); GL2 gl = drawingTools.getGl().getGL2(); gl.glCallList(glName); } else { if (drawer != null) { drawer.draw(drawingTools); } } } /** * Synchronize the display list. * @param drawingTools drawing tools. */ private void synchronize(JoGLDrawingTools drawingTools) { GL2 gl = drawingTools.getGl().getGL2(); // Check glName. if ((glName == null) || !(gl.glIsList(glName))) { glName = gl.glGenLists(1); upToDate = false; } // Check up to date. if (!upToDate) { gl.glNewList(glName, GL2.GL_COMPILE); if (drawer != null) { drawer.draw(drawingTools); } gl.glEndList(); upToDate = true; } } /** * Dispose resources. * @param gl the current OpenGl context. */ void dispose(GL2 gl) { if ((glName != null) && gl.glIsList(glName)) { gl.glDeleteLists(glName, 1); glName = null; upToDate = false; } } } JoGLRendererManager.java000066400000000000000000000057611212506735300344040ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/renderer/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.renderer; import org.scilab.forge.scirenderer.implementation.jogl.JoGLDrawingTools; import org.scilab.forge.scirenderer.renderer.Renderer; import org.scilab.forge.scirenderer.renderer.RendererManager; import javax.media.opengl.GL2; import java.util.HashSet; import java.util.Set; import java.util.Stack; /** * @author Pierre Lando */ public class JoGLRendererManager implements RendererManager { /** * Set of current renderer. */ private final Set rendererSet = new HashSet(); /** * Set of dead buffers. */ private final Stack deadRendererSet = new Stack(); /** * Default constructor. */ public JoGLRendererManager() { } @Override public Renderer createRenderer() { JoGLRenderer newRenderer = new JoGLRenderer(); rendererSet.add(newRenderer); return newRenderer; } @Override public void dispose(Renderer renderer) { if ((renderer != null) && (renderer instanceof JoGLRenderer)) { JoGLRenderer localRenderer = (JoGLRenderer) renderer; rendererSet.remove(localRenderer); deadRendererSet.push(localRenderer); } } public void dispose(JoGLDrawingTools drawingTools, Renderer renderer) { if ((renderer != null) && (renderer instanceof JoGLRenderer)) { JoGLRenderer localRenderer = (JoGLRenderer) renderer; localRenderer.dispose(drawingTools.getGl().getGL2()); rendererSet.remove(localRenderer); deadRendererSet.push(localRenderer); } } /** * Perform a draw with the given renderer to the given canvas.. * @param drawingTools the given drawing tools. * @param renderer the given renderer. */ public void draw(JoGLDrawingTools drawingTools, Renderer renderer) { if ((renderer != null) && (renderer instanceof JoGLRenderer)) { ((JoGLRenderer) renderer).draw(drawingTools); } } /** * Ask all {@link JoGLRenderer} to reload. * This is needed when the OpenGl context has been lost. */ public void glReload() { for (JoGLRenderer renderer : rendererSet) { renderer.reload(); } } /** * Synchronize to OpenGl context. * Mostly consist to dispose dead renderer resources. * @param gl the current OpenGl context. */ public void glSynchronize(GL2 gl) { while (!deadRendererSet.isEmpty()) { deadRendererSet.pop().dispose(gl); } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/texture/000077500000000000000000000000001212506735300277245ustar00rootroot00000000000000JoGLTextureManager.java000066400000000000000000000476551212506735300342000ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/texture/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.texture; import com.jogamp.opengl.util.awt.TextureRenderer; import com.jogamp.opengl.util.texture.TextureCoords; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.implementation.jogl.JoGLCanvas; import org.scilab.forge.scirenderer.implementation.jogl.JoGLDrawingTools; import org.scilab.forge.scirenderer.texture.AbstractTexture; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureManager; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.TransformationManager; import org.scilab.forge.scirenderer.tranformations.Vector3d; import javax.media.opengl.GLContext; import javax.media.opengl.GL2; import java.awt.AlphaComposite; import java.awt.Dimension; import java.awt.Graphics2D; import java.nio.FloatBuffer; import java.util.Collection; import java.util.HashSet; import java.util.Set; /** * @author Pierre Lando */ public class JoGLTextureManager implements TextureManager { private final Set allTextures = new HashSet(); private final Set toDispose = new HashSet(); JoGLCanvas canvas; public JoGLTextureManager(JoGLCanvas canvas) { this.canvas = canvas; } /** * Texture binder. * Bind the given texture to the given OpenGl context. * @param drawingTools drawing tools. * @param texture given texture. * @throws org.scilab.forge.scirenderer.SciRendererException if the texture can't be bind. */ public void bind(JoGLDrawingTools drawingTools, Texture texture) throws SciRendererException { if ((texture instanceof JoGLTexture) && (allTextures.contains((JoGLTexture) texture))) { ((JoGLTexture) texture).bind(drawingTools); } } /** * Draw the given texture. * @param drawingTools used drawing tools. * @param texture the texture too drawn. * @throws org.scilab.forge.scirenderer.SciRendererException if the texture is invalid. */ public void draw(JoGLDrawingTools drawingTools, Texture texture) throws SciRendererException { if ((texture instanceof JoGLTexture) && (allTextures.contains((JoGLTexture) texture))) { final JoGLTexture jt = (JoGLTexture) texture; jt.preDraw(drawingTools); jt.draw(drawingTools); jt.postDraw(drawingTools); } } public void draw(JoGLDrawingTools drawingTools, Texture texture, AnchorPosition anchor, ElementsBuffer positions, double rotationAngle) throws SciRendererException { if ((texture instanceof JoGLTexture) && (allTextures.contains((JoGLTexture) texture))) { if (positions != null) { FloatBuffer data = positions.getData(); if (data != null) { data.rewind(); float[] position = {0, 0, 0, 1}; final JoGLTexture jt = (JoGLTexture) texture; jt.preDraw(drawingTools); while (data.remaining() >= 4) { data.get(position); jt.draw(drawingTools, anchor, new Vector3d(position), rotationAngle); } jt.postDraw(drawingTools); } } } } public void draw(JoGLDrawingTools drawingTools, Texture texture, AnchorPosition anchor, Vector3d position, double rotationAngle) throws SciRendererException { if ((texture instanceof JoGLTexture) && (allTextures.contains((JoGLTexture) texture))) { final JoGLTexture jt = (JoGLTexture) texture; jt.preDraw(drawingTools); jt.draw(drawingTools, anchor, position, rotationAngle); jt.postDraw(drawingTools); } } /** Called when gl context is gone. */ public void glReload() { for (JoGLTexture texture : allTextures) { texture.glReload(); } } @Override public Texture createTexture() { JoGLTexture texture = new JoGLTexture(); allTextures.add(texture); return texture; } @Override public void dispose(Collection textures) { for (Texture texture : textures) { dispose(texture); } } @Override public void dispose(Texture texture) { if ((texture instanceof JoGLTexture) && (allTextures.contains((JoGLTexture) texture))) { allTextures.remove((JoGLTexture) texture); synchronized (toDispose) { toDispose.add((JoGLTexture) texture); } } } /** * Inner class for {@link Texture} implementation. */ public class JoGLTexture extends AbstractTexture implements Texture { private com.jogamp.opengl.util.texture.Texture[] textures; private int wCuts; private int hCuts; private double sfactor = 1; private double tfactor = 1; /** * Default constructor. */ public JoGLTexture() { } /** * Bind the texture in the OpenGl context. * @param drawingTools current drawing tools. * @throws SciRendererException if the texture is invalid. */ public synchronized void bind(JoGLDrawingTools drawingTools) throws SciRendererException { GL2 gl = drawingTools.getGl().getGL2(); if (isValid()) { checkData(drawingTools); if (textures.length == 1) { gl.glEnable(GL2.GL_TEXTURE_2D); gl.glEnable(GL2.GL_BLEND); gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA); gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE); textures[0].setTexParameteri(gl, GL2.GL_TEXTURE_MAG_FILTER, getAsGLFilter(getMagnificationFilter(), false)); textures[0].setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, getAsGLFilter(getMinifyingFilter(), false)); if (gl.isNPOTTextureAvailable()) { textures[0].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, getAsGLWrappingMode(getSWrappingMode())); textures[0].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T, getAsGLWrappingMode(getTWrappingMode())); } else { textures[0].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE); textures[0].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE); } gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE); textures[0].bind(gl); /* sfactor and tfactor are useful to have the correct texture coordinates when the texture was transformed into a power-of-two texture */ Dimension textureSize = getDataProvider().getTextureSize(); sfactor = (double) textureSize.width / (double) textures[0].getWidth(); tfactor = (double) textureSize.height / (double) textures[0].getHeight(); } else { throw new SciRendererException("Texture is too large"); } } else { throw new SciRendererException("Texture have no data."); } } /** * Check if the texture data are up to date. * @param drawingTools the drawing tools. * @throws SciRendererException if the texture is too big. */ private synchronized void checkData(JoGLDrawingTools drawingTools) throws SciRendererException { synchronized (toDispose) { if (!toDispose.isEmpty()) { final GL2 gl = drawingTools.getGl().getGL2(); for (JoGLTexture jt : toDispose) { jt.releaseTextures(gl); } toDispose.clear(); } } if (isValid() && !upToDate) { GL2 gl = drawingTools.getGl().getGL2(); releaseTextures(gl); Dimension textureSize = getDataProvider().getTextureSize(); int maxSize = drawingTools.getGLCapacity().getMaximumTextureSize(); wCuts = (int) Math.ceil(textureSize.getWidth() / maxSize); hCuts = (int) Math.ceil(textureSize.getHeight() / maxSize); textures = new com.jogamp.opengl.util.texture.Texture[wCuts * hCuts]; int k = 0; for (int i = 0; i < wCuts; i++) { for (int j = 0; j < hCuts; j++) { int x = i * maxSize; int y = j * maxSize; int width = getSubTextureSize((i == (wCuts - 1)), textureSize.width, maxSize); int height = getSubTextureSize((j == (hCuts - 1)), textureSize.height, maxSize); TextureRenderer renderer = new TextureRenderer(width, height, true, false); Graphics2D g2d = renderer.createGraphics(); g2d.setComposite(AlphaComposite.Src); g2d.drawImage(getDataProvider().getSubImage(x, y, width, height), null, 0, 0); g2d.dispose(); renderer.markDirty(0, 0, width, height); textures[k] = renderer.getTexture(); k++; } } upToDate = true; } } private void releaseTextures(GL2 gl) { if (textures != null) { for (com.jogamp.opengl.util.texture.Texture texture : textures) { texture.destroy(gl); } textures = null; } } public void preDraw(JoGLDrawingTools drawingTools) throws SciRendererException { checkData(drawingTools); final GL2 gl = drawingTools.getGl().getGL2(); gl.glMatrixMode(GL2.GL_TEXTURE); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glEnable(GL2.GL_TEXTURE_2D); gl.glEnable(GL2.GL_BLEND); gl.glBlendFunc(GL2.GL_ONE, GL2.GL_ONE_MINUS_SRC_ALPHA); gl.glEnable(GL2.GL_ALPHA_TEST); gl.glAlphaFunc(GL2.GL_GREATER, 0.0f); gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS); gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE); for (int k = 0; k < wCuts * hCuts; k++) { textures[k].enable(gl); textures[k].setTexParameteri(gl, GL2.GL_TEXTURE_MAG_FILTER, getAsGLFilter(getMagnificationFilter(), false)); textures[k].setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER, getAsGLFilter(getMinifyingFilter(), false)); if (gl.isNPOTTextureAvailable()) { textures[k].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, getAsGLWrappingMode(getSWrappingMode())); textures[k].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T, getAsGLWrappingMode(getTWrappingMode())); } else { textures[k].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE); textures[k].setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE); } textures[k].bind(gl); } } public void draw(JoGLDrawingTools drawingTools, AnchorPosition anchor, Vector3d position, double rotationAngle) throws SciRendererException { TransformationManager transformationManager = drawingTools.getTransformationManager(); Transformation canvasProjection = transformationManager.getCanvasProjection(); boolean sceneCoordinate = drawingTools.getTransformationManager().isUsingSceneCoordinate(); Dimension dimension = drawingTools.getCanvas().getDimension(); Vector3d projected; final GL2 gl = drawingTools.getGl().getGL2(); if (sceneCoordinate) { projected = canvasProjection.project(position); } else { projected = position; } gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glOrtho(0, dimension.width, 0, dimension.height, 1, -1); if (rotationAngle == 0) { gl.glTranslated(Math.round(projected.getX() + getAnchorDeltaX(anchor)), Math.round(projected.getY() + getAnchorDeltaY(anchor)), projected.getZ()); } else { gl.glTranslated(Math.round(projected.getX()), Math.round(projected.getY()), projected.getZ()); gl.glRotated(rotationAngle, 0, 0, 1); gl.glTranslated(Math.round(getAnchorDeltaX(anchor)), Math.round(getAnchorDeltaY(anchor)), 0); } draw(drawingTools); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glPopMatrix(); } public void postDraw(JoGLDrawingTools drawingTools) { final GL2 gl = drawingTools.getGl().getGL2(); for (int k = 0; k < wCuts * hCuts; k++) { textures[k].disable(gl); } gl.glPopAttrib(); gl.glDisable(GL2.GL_ALPHA_TEST); gl.glDisable(GL2.GL_TEXTURE_2D); gl.glDisable(GL2.GL_BLEND); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glPopMatrix(); gl.glMatrixMode(GL2.GL_TEXTURE); gl.glPopMatrix(); } /** * Draw the texture in XY plane. * @param drawingTools the drawing tools. * @throws SciRendererException if the texture is invalid. */ public void draw(JoGLDrawingTools drawingTools) throws SciRendererException { final int maxSize = drawingTools.getGLCapacity().getMaximumTextureSize(); final Dimension textureSize = getDataProvider().getTextureSize(); final GL2 gl = drawingTools.getGl().getGL2(); if (textureSize != null) { int k = 0; for (int i = 0; i < wCuts; i++) { for (int j = 0; j < hCuts; j++) { final int x = i * maxSize; final int y = j * maxSize; final int width = getSubTextureSize((i == (wCuts - 1)), textureSize.width, maxSize); final int height = getSubTextureSize((j == (hCuts - 1)), textureSize.height, maxSize); // if the texture has been transformed in a power-of-two texture we need to have the correct coords. final TextureCoords coords = textures[k].getSubImageTexCoords(0, 0, width, height); gl.glBegin(GL2.GL_QUADS); gl.glTexCoord2f(coords.left(), coords.bottom()); gl.glVertex2f(x, y); gl.glTexCoord2f(coords.right(), coords.bottom()); gl.glVertex2f(x + width, y); gl.glTexCoord2f(coords.right(), coords.top()); gl.glVertex2f(x + width, y + height); gl.glTexCoord2f(coords.left(), coords.top()); gl.glVertex2f(x, y + height); gl.glEnd(); k++; } } } } @Override public double getSScaleFactor() { return sfactor; } @Override public double getTScaleFactor() { return tfactor; } /** * Compute the sub texture size. * @param lastPart true if this is the last part. * @param textureSize the global texture size. * @param maxSize the maximum sub-texture size. * @return the sub texture size. */ private int getSubTextureSize(boolean lastPart, int textureSize, int maxSize) { if (lastPart) { int lastSize = textureSize % maxSize; if (lastSize == 0) { return maxSize; } else { return lastSize; } } else { return maxSize; } } private int getAsGLWrappingMode(Texture.Wrap wrappingMode) { switch (wrappingMode) { case CLAMP: return GL2.GL_CLAMP_TO_EDGE; case REPEAT: return GL2.GL_REPEAT; default: return GL2.GL_REPEAT; } } private int getAsGLFilter(Texture.Filter filter, boolean mipmap) { int returnedValue; if (mipmap) { switch (filter) { case LINEAR: returnedValue = GL2.GL_LINEAR_MIPMAP_LINEAR; break; case NEAREST: returnedValue = GL2.GL_NEAREST_MIPMAP_NEAREST; break; default: returnedValue = GL2.GL_NEAREST; break; } } else { switch (filter) { case LINEAR: returnedValue = GL2.GL_LINEAR; break; case NEAREST: returnedValue = GL2.GL_NEAREST; break; default: returnedValue = GL2.GL_NEAREST; break; } } return returnedValue; } /** Called when gl context is gone. */ public void glReload() { textures = null; upToDate = false; } /** * Return the deltaX to apply to the sprite in regards to the given anchor. * @param anchor the given anchor. * @return the deltaX to apply to the sprite in regards to the given anchor. */ protected double getAnchorDeltaX(AnchorPosition anchor) { int spriteWidth = getDataProvider().getTextureSize().width; switch (anchor) { case LEFT: case LOWER_LEFT: case UPPER_LEFT: return 0; case UP: case CENTER: case DOWN: return -spriteWidth / 2f; case RIGHT: case LOWER_RIGHT: case UPPER_RIGHT: return -spriteWidth; default: return 0; } } /** * Return the deltaY to apply to the sprite in regards to the given anchor. * @param anchor the given anchor. * @return the deltaY to apply to the sprite in regards to the given anchor. */ protected double getAnchorDeltaY(AnchorPosition anchor) { int spriteHeight = getDataProvider().getTextureSize().height; switch (anchor) { case UPPER_LEFT: case UP: case UPPER_RIGHT: return -spriteHeight; case LEFT: case CENTER: case RIGHT: return -spriteHeight / 2f; case LOWER_LEFT: case DOWN: case LOWER_RIGHT: return 0; default: return 0; } } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/utils/000077500000000000000000000000001212506735300273645ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/utils/G2DShortCuts.java000066400000000000000000000032521212506735300324640ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.utils; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import java.awt.BasicStroke; import java.awt.Graphics2D; import java.awt.Stroke; /** * * Utility class for common {@link java.awt.Graphics2D} calls. * * @author Pierre Lando */ public final class G2DShortCuts { /** * Private constructor: this is an utility class. */ private G2DShortCuts() { } /** * Use the given color for drawing. * @param g2d the {@link Graphics2D} where the color will be used. * @param c the given color. */ public static void useColor(Graphics2D g2d, Color c) { java.awt.Color color = new java.awt.Color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); g2d.setColor(color); } /** * Use the given appearance for drawing lines. * @param g2d the {@link Graphics2D} where the appearance will be used. * @param appearance the given appearance. */ public static void useLineAppearance(Graphics2D g2d, Appearance appearance) { // TODO : add line pattern. Stroke stroke = new BasicStroke(appearance.getLineWidth()); g2d.setStroke(stroke); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/implementation/jogl/utils/GLShortCuts.java000066400000000000000000000063761212506735300324240ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.implementation.jogl.utils; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import javax.media.opengl.GL2; /** * * Utility class for common OpenGl calls. * * @author Pierre Lando */ public final class GLShortCuts { private static final short FULL_LINE_PATTERN = (short) 0xFFFF; /** * Private constructor. * This is an utility class. */ private GLShortCuts() { } /** * Set the OpenGl context line appearance from the given appearance. * If appearance is null, default value are used.. * @param gl the OpenGl context. * @param appearance the appearance to use. */ public static void useLineAppearance(GL2 gl, Appearance appearance) { Appearance usedAppearance; if (appearance == null) { usedAppearance = new Appearance(); } else { usedAppearance = appearance; } useColor(gl, usedAppearance.getLineColor()); gl.glLineWidth(getClampedLineWidth(gl, usedAppearance.getLineWidth())); short pattern = usedAppearance.getLinePattern(); if (pattern != FULL_LINE_PATTERN) { gl.glEnable(GL2.GL_LINE_STIPPLE); gl.glLineStipple((int) usedAppearance.getLineWidth(), pattern); } else { gl.glDisable(GL2.GL_LINE_STIPPLE); } } /** * Return given lineWidth clamped to lineWidth range. * @param gl the current gl context. * @param lineWidth given line width. * @return given lineWidth clamped to lineWidth range. */ private static float getClampedLineWidth(GL2 gl, float lineWidth) { float[] range = new float[]{1f, 1f}; if (gl.glIsEnabled(GL2.GL_LINE_SMOOTH)) { gl.glGetFloatv(GL2.GL_SMOOTH_LINE_WIDTH_RANGE, range, 0); } else { gl.glGetFloatv(GL2.GL_ALIASED_LINE_WIDTH_RANGE, range, 0); } if (lineWidth < range[0]) { return range[0]; } else if (lineWidth > range[1]) { return range[1]; } else { return lineWidth; } } /** * Set the OpenGl context color to the given color. * @param gl the OpenGl context. * @param color the color to use. */ public static void useColor(GL2 gl, Color color) { if (color != null) { gl.glColor3f(color.getRedAsFloat(), color.getGreenAsFloat(), color.getBlueAsFloat()); } } /** * Enable or disable GL option. * @param gl the current gl. * @param option the option to change. * @param status the new option status. */ public static void setEnable(GL2 gl, int option, boolean status) { if (status) { gl.glEnable(option); } else { gl.glDisable(option); } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/lightning/000077500000000000000000000000001212506735300242275ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/lightning/Light.java000066400000000000000000000051601212506735300261430ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.lightning; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * The light interface. * * @author Pierre Lando */ public interface Light { /** * Return the status of this light. * @return the status of this light. */ boolean isEnable(); /** * Set the status of this light. * @param enable the new status of this light. */ void setEnable(boolean enable); /** * Return the ambient color of this light; * @return the ambient color of this light; */ Color getAmbientColor(); /** * Set the ambient color of this light. * @param color the new ambient color of this light. */ void setAmbientColor(Color color); /** * Return the diffuse color of this light; * @return the diffuse color of this light; */ Color getDiffuseColor(); /** * Set the diffuse color of this light. * @param color the new diffuse color of this light. */ void setDiffuseColor(Color color); /** * Return the specular color of this light; * @return the specular color of this light; */ Color getSpecularColor(); /** * Set the specular color of this light. * @param color the new specular color of this light. */ void setSpecularColor(Color color); /** * Return the light position. * @return the light position. */ Vector3d getPosition(); /** * Set the light position. * @param position the new position. */ void setPosition(Vector3d position); /** * Return the spot direction. * @return the spot direction. */ Vector3d getSpotDirection(); /** * Set the spot direction. * @param spotDirection the new spot direction. */ void setSpotDirection(Vector3d spotDirection); /** * Return the spot angle. * @return the spot angle. */ float getSpotAngle(); /** * Set the spot angle. * @param angle the new spot angle. */ void setSpotAngle(float angle); /** * Return the light index. * @return the light index. */ int getIndex(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/lightning/LightManager.java000066400000000000000000000026071212506735300274410ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.lightning; /** * Light manager interface. * * @author Pierre Lando */ public interface LightManager { /** * The default lightning status. */ boolean DEFAULT_LIGHTNING_STATUS = false; /** * Return the number of available light. * @return the number of available light. */ int getLightNumber(); /** * Return the i-th light. * {@code null} is returned if i is not a valid index. * @param i the given index. * @return the i-th light. */ Light getLight(int i); /** * Set the lightning status. * Lighting is initially disabled. * When it is enabled, light sources that are enabled contribute to the lighting calculation. * @param isLightningEnable the new lightning status. */ void setLightningEnable(boolean isLightningEnable); /** * Return the lightning status. * @return the lightning status. */ boolean isLightningEnable(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/picking/000077500000000000000000000000001212506735300236705ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/picking/PickingManager.java000066400000000000000000000013101212506735300274050ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.picking; /** * * Interface for a picking manager. * * @author Pierre Lando */ public interface PickingManager { /** * Add a picking task. * @param pickingTask the new picking task. */ void addPickingTask(PickingTask pickingTask); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/picking/PickingTask.java000066400000000000000000000013051212506735300267410ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.picking; /** * Interface for a picking task. * * @author Pierre Lando */ public interface PickingTask { /** * Call to perform the task. * @param pickingTools the picking tools to use. */ void perform(PickingTools pickingTools); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/picking/PickingTools.java000066400000000000000000000020661212506735300271440ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.picking; import java.awt.Point; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * Interface for picking tools. * * @author Pierre Lando */ public interface PickingTools { /** * Return the scene coordinate of the pixel under the given windows position. * @param windowPosition the given window position. * @return the scene coordinate of the pixel under the given windows position. */ Vector3d getUnderlyingPoint(Point windowPosition); /** * Return the canvas. * @return the canvas. */ Canvas getCanvas(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/renderer/000077500000000000000000000000001212506735300240525ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/renderer/Renderer.java000066400000000000000000000020321212506735300264600ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.renderer; import org.scilab.forge.scirenderer.Drawer; /** * * Interface for a renderer. * * A renderer is used to improve drawing performance. * If you have an uge static object to draw at each frame, encapsulate his drawer in a renderer improve drawing performance. * * @author Pierre Lando */ public interface Renderer { /** * Set the drawer. * @param drawer the new drawer. */ void setDrawer(Drawer drawer); /** * Return the drawer. * @return the drawer. */ Drawer getDrawer(); /** * Ask for reload. */ void reload(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/renderer/RendererManager.java000066400000000000000000000015021212506735300277540ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.renderer; /** * * Interface for renderer manager. * * @author Pierre Lando */ public interface RendererManager { /** * Create a new renderer. * @return a new renderer. */ Renderer createRenderer(); /** * Release all resources used by the given renderer. * @param renderer the given renderer. */ void dispose(Renderer renderer); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/000077500000000000000000000000001212506735300233755ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/DefaultRulerModel.java000066400000000000000000000240411212506735300276200ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler; import org.scilab.forge.scirenderer.ruler.graduations.Graduations; import org.scilab.forge.scirenderer.ruler.graduations.LinearGraduations; import org.scilab.forge.scirenderer.ruler.graduations.LogarithmicGraduations; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * Default ruler model. * * @author Pierre Lando */ public final class DefaultRulerModel implements RulerModel { /** * Value associated with the first point. */ private double firstValue = DEFAULT_FIRST_VALUE; /** * Value associated with the second point. */ private double secondValue = DEFAULT_SECOND_VALUE; /** * First point position in world coordinate. */ private Vector3d firstPoint = DEFAULT_FIRST_POINT; /** * Second point position in world coordinate. */ private Vector3d secondPoint = DEFAULT_SECOND_POINT; /** * Ticks direction, in world coordinate. */ private Vector3d ticksDirection = DEFAULT_TICKS_DIRECTION; /** * Ticks length, in pixel. */ private int ticksLength = DEFAULT_TICK_LENGTH; /** * Sub ticks length, in pixel. */ private int subTicksLength = DEFAULT_SUB_TICK_LENGTH; /** * Minimal sub-ticks distance. */ private double minimalSubTicksDistance = DEFAULT_MINIMAL_SUB_TICKS_DISTANCE; /** * Sprite distance to segment, in pixel. */ private int spriteDistance = DEFAULT_SPRITE_DISTANCE; /** * The graduations. */ private Graduations graduations; /** * Current margin. * The margin is the minimal allowed distance between to sprite of the same ruler. */ private double margin = DEFAULT_MARGIN; /** * Current line visibility. */ private boolean lineVisible = DEFAULT_LINE_VISIBLE; /** * Auto-ticks status. */ private boolean isAutoTicks = DEFAULT_AUTO_TICKS_STATUS; /** * Logarithmic status. */ private boolean isLogarithmic = DEFAULT_LOGARITHMIC_STATUS; /** * Current color. */ private Color color = DEFAULT_COLOR; /** * Used graduations when {@link this#isAutoTicks} is false. */ private Graduations userGraduation; /** * Line width */ private double lineWidth = DEFAULT_LINE_WIDTH; private int subticksNumber = -1; /** * Default constructor. */ public DefaultRulerModel() { } @Override public double getFirstValue() { return firstValue; } /** * First value setter. * @param firstValue the new first value. */ public void setFirstValue(double firstValue) { graduations = null; this.firstValue = (Double.isInfinite(firstValue) ? Double.MAX_VALUE : firstValue); } @Override public double getSecondValue() { return secondValue; } /** * Second value setter. * @param secondValue the new second value. */ public void setSecondValue(double secondValue) { graduations = null; this.secondValue = (Double.isInfinite(secondValue) ? Double.MAX_VALUE : secondValue); } /** * Set the first and second value in one call. * @param firstValue the first value. * @param secondValue the second value. */ public void setValues(double firstValue, double secondValue) { setFirstValue(firstValue); setSecondValue(secondValue); } @Override public Vector3d getFirstPoint() { return firstPoint; } /** * First point setter. * @param firstPoint the new first point. */ public void setFirstPoint(Vector3d firstPoint) { this.firstPoint = firstPoint; } @Override public Vector3d getSecondPoint() { return secondPoint; } /** * Second point setter. * @param secondPoint the new second point. */ public void setSecondPoint(Vector3d secondPoint) { this.secondPoint = secondPoint; } /** * Point setter. * @param firstPoint the new first point. * @param secondPoint the new second point. */ public void setPoints(Vector3d firstPoint, Vector3d secondPoint) { this.firstPoint = firstPoint; this.secondPoint = secondPoint; } @Override public Vector3d getTicksDirection() { return ticksDirection; } /** * Ticks direction setter. * @param ticksDirection the new ticks direction. */ public void setTicksDirection(Vector3d ticksDirection) { this.ticksDirection = ticksDirection; } @Override public int getTicksLength() { return ticksLength; } /** * Ticks length setter. * @param ticksLength the new tick length in pixels. */ public void setTicksLength(int ticksLength) { this.ticksLength = ticksLength; } @Override public int getSubTicksLength() { return subTicksLength; } /** * Sub-ticks length setter. * @param subTicksLength the new sub-tick length in pixels. */ public void setSubTicksLength(int subTicksLength) { this.subTicksLength = subTicksLength; } @Override public Graduations getGraduations() { if (isAutoTicks) { if (graduations == null) { if (isLogarithmic) { graduations = LogarithmicGraduations.create(getFirstValue(), getSecondValue()); } else { graduations = LinearGraduations.create(getFirstValue(), getSecondValue()); } } return graduations; } else { return userGraduation; } } /** * User graduation setter. * @param graduations the new user-defined graduations. */ public void setUserGraduation(Graduations graduations) { this.userGraduation = graduations; } @Override public Vector3d getPosition(double value) { if ((firstPoint != null) && (secondPoint != null)) { if (isLogarithmic()) { double valueLog = Math.log10(value); double firstValueLog = Math.log10(firstValue); double secondValueLog = Math.log10(secondValue); double s = (secondValueLog - firstValueLog); double k1 = (valueLog - firstValueLog) / s; double k2 = (secondValueLog - valueLog) / s; return firstPoint.times(k2).plus(secondPoint.times(k1)); } else { double s = (secondValue - firstValue); return firstPoint.times((secondValue - value) / s).plus(secondPoint.times((value - firstValue) / s)); } } else { return null; } } @Override public double getMargin() { return margin; } /** * Margin setter. * The margin is minimal distance accepted between ticks labels. * @param margin the new margin value. */ public void setMargin(double margin) { this.margin = margin; } @Override public boolean isLineVisible() { return lineVisible; } /** * Line visibility setter. * @param lineVisible the new line visibility status. */ public void setLineVisible(boolean lineVisible) { this.lineVisible = lineVisible; } @Override public boolean isAutoTicks() { return isAutoTicks; } /** * Auto-ticks parameter setter. * If it set to {@code false}, the user defined graduation will be used. * @param isAutoTicks the new auto-ticks status. */ public void setAutoTicks(boolean isAutoTicks) { this.isAutoTicks = isAutoTicks; } @Override public boolean isLogarithmic() { return isLogarithmic; } /** * Logarithmic or linear setter * @param isLogarithmic the new logarithmic status. */ public void setLogarithmic(boolean isLogarithmic) { if (isLogarithmic != this.isLogarithmic) { this.isLogarithmic = isLogarithmic; graduations = null; } } @Override public int getSpriteDistance() { return spriteDistance; } /** * Sprite distance setter. * @param spriteDistance the new sprite distance to the main ticks in pixel. */ public void setSpriteDistance(int spriteDistance) { this.spriteDistance = spriteDistance; } @Override public double getMinimalSubTicksDistance() { return minimalSubTicksDistance; } /** * Minimal accepted distance between sub-ticks setter. * @param minimalSubTicksDistance the new minimal accepted distance between sub-ticks. */ public void setMinimalSubTicksDistance(double minimalSubTicksDistance) { this.minimalSubTicksDistance = minimalSubTicksDistance; } @Override public Color getColor() { return color; } /** * Ruler color setter. * @param color the new rule color. */ public void setColor(Color color) { this.color = color; } @Override public double getLineWidth() { return lineWidth; } /** * Ruler line width setter * @param lineWidth the new line width */ public void setLineWidth(double lineWidth) { this.lineWidth = lineWidth; } @Override public int getSubticksNumber() { return subticksNumber; } /** * Set number of subticks. * @param N the number of subticks or -1 if the computation is automatic. */ public void setSubticksNumber(int N) { this.subticksNumber = N; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/DefaultRulerSpriteFactory.java000066400000000000000000000036751212506735300313700ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.texture.TextEntity; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureDrawer; import org.scilab.forge.scirenderer.texture.TextureDrawingTools; import org.scilab.forge.scirenderer.texture.TextureManager; import java.awt.Dimension; import java.text.DecimalFormat; /** * @author Pierre Lando */ public final class DefaultRulerSpriteFactory implements RulerSpriteFactory { /** * Default constructor. */ public DefaultRulerSpriteFactory() { } @Override public Texture create(double value, DecimalFormat adaptedFormat, TextureManager textureManager) { String text = adaptedFormat.format(value); final TextEntity textEntity = new TextEntity(text); textEntity.setTextColor(new Color(0, 0, 0)); textEntity.setTextAntiAliased(false); Texture texture = textureManager.createTexture(); texture.setDrawer(new TextureDrawer() { @Override public void draw(TextureDrawingTools drawingTools) { drawingTools.draw(textEntity, 0, 0); } @Override public Dimension getTextureSize() { return textEntity.getSize(); } @Override public OriginPosition getOriginPosition() { return OriginPosition.UPPER_LEFT; } }); return texture; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/RulerDrawer.java000066400000000000000000000711741212506735300265100ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * Copyright (C) 2012 - Scilab Enterprises - Bruno JOFRET * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler; import java.awt.Dimension; import java.awt.geom.Rectangle2D; import java.nio.FloatBuffer; import java.text.DecimalFormat; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.scilab.forge.scirenderer.DrawingTools; import org.scilab.forge.scirenderer.SciRendererException; import org.scilab.forge.scirenderer.buffers.BuffersManager; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.ruler.graduations.Graduations; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.geometry.DefaultGeometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.texture.AnchorPosition; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureManager; import org.scilab.forge.scirenderer.tranformations.Transformation; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Pierre Lando */ public class RulerDrawer { /** * Sprite map. */ private final Map spriteMap = new ConcurrentHashMap(); /** * The current {@link TextureManager}. */ private final TextureManager textureManager; /** * The used {@link RulerSpriteFactory}. */ private RulerSpriteFactory spriteFactory; private OneShotRulerDrawer oneShotRulerDrawer; /** * Ruler drawer constructor. * @param textureManager the {@link TextureManager} of the canvas where the ruler will be drawn. */ public RulerDrawer(TextureManager textureManager) { this.textureManager = textureManager; this.spriteFactory = new DefaultRulerSpriteFactory(); this.oneShotRulerDrawer = new OneShotRulerDrawer(); } /** * Ruler drawing method. * @param drawingTools the {@link DrawingTools} of the canvas where the ruler will be drawn. * @param model the {@link RulerModel} of the drawn ruler. * @return the {@link RulerDrawingResult} give information about how the ruler have been drawn. */ public RulerDrawingResult draw(DrawingTools drawingTools, RulerModel model) { return oneShotRulerDrawer.drawWithResults(drawingTools, model); } /** * Draw the ruler * @param drawingTools the {@link DrawingTools} of the canvas where the ruler will be drawn. */ public void draw(DrawingTools drawingTools) { oneShotRulerDrawer.draw(drawingTools); } /** * Get the model * @return the ruler model. */ public RulerModel getModel() { return oneShotRulerDrawer.rulerModel; } /** * Get the subticks values * @return the values. */ public List getSubTicksValue() { return oneShotRulerDrawer.subTicksValue; } /** * Get the ticks values * @return the values. */ public List getTicksValue() { return oneShotRulerDrawer.ticksValue; } /** * Compute different parameters on a ruler * @param drawingTools the {@link DrawingTools} of the canvas where the ruler will be drawn. * @param rulerModel the {@link RulerModel} of the drawn ruler. * @param canvasProjection the canvas projection. */ public RulerDrawingResult computeRuler(DrawingTools drawingTools, RulerModel model, Transformation canvasProjection) { return oneShotRulerDrawer.computeRuler(drawingTools, model, canvasProjection); } /** * Set the current {@link RulerSpriteFactory}. * All existing sprite will be cleared. * This ruler drawer will use the new {@link RulerSpriteFactory}. * @param spriteFactory the new {@link RulerSpriteFactory}. */ public void setSpriteFactory(RulerSpriteFactory spriteFactory) { disposeResources(); this.spriteFactory = spriteFactory; } /** * Dispose all used resources. */ public void disposeResources() { textureManager.dispose(spriteMap.values()); spriteMap.clear(); oneShotRulerDrawer.dispose(); } /** * This class actually perform all the rendering of one ruler. */ private class OneShotRulerDrawer { private Transformation canvasProjection; private RulerModel rulerModel; private Vector3d windowSubTicksDelta; private Vector3d windowTicksDelta; /** * Sprite Dimension map. Used as cached values in order not to charge DataProvider. */ private Map spriteDimensionMap = new HashMap(); private List spritesList = new LinkedList(); /** * The maximum distance corresponding to the actually displayed sprites. */ private double maximalSpritesDistance; /** * Deepest possible {@see Graduations} */ private Graduations graduations; private List subTicksValue; private List ticksValue; private int density; public OneShotRulerDrawer() { } public synchronized void dispose() { spriteDimensionMap.clear(); spritesList.clear(); if (subTicksValue != null) { subTicksValue.clear(); } if (ticksValue != null) { ticksValue.clear(); } rulerModel = null; } /** * Compute different parameters on a ruler * @param drawingTools the {@link DrawingTools} of the canvas where the ruler will be drawn. * @param rulerModel the {@link RulerModel} of the drawn ruler. * @param canvasProjection the canvas projection. */ public synchronized RulerDrawingResult computeRuler(DrawingTools drawingTools, RulerModel rulerModel, Transformation canvasProjection) { // Same code as drawWithResults (without drawing) // Historically, computations were made when drawing and they are made before drawing. // TODO: remove drawWithResults ?? this.canvasProjection = canvasProjection; this.rulerModel = rulerModel; subTicksValue = new LinkedList(); ticksValue = new LinkedList(); spritesList = new LinkedList(); Vector3d windowTicksDirection = canvasProjection.projectDirection(rulerModel.getTicksDirection()); windowTicksDirection = windowTicksDirection.setZ(0); Vector3d normalizedProjectedTicksDirection = windowTicksDirection.getNormalized(); windowSubTicksDelta = normalizedProjectedTicksDirection.times(rulerModel.getSubTicksLength()); windowTicksDelta = normalizedProjectedTicksDirection.times(rulerModel.getTicksLength()); DecimalFormat format; if (rulerModel.isAutoTicks()) { format = computeAutoGraduation(); } else { format = computeUserGraduation(); } computeTicksData(); double distRatio = computeTicksDistanceRatio(windowTicksDirection.getNorm()); return new RulerDrawingResult(format, ticksValue, subTicksValue, density, distRatio, normalizedProjectedTicksDirection); } /** * Constructor. * @param drawingTools the {@link DrawingTools} of the canvas where the ruler will be drawn. * @param rulerModel the {@link RulerModel} of the drawn ruler. */ public synchronized RulerDrawingResult drawWithResults(DrawingTools drawingTools, RulerModel rulerModel) { this.rulerModel = rulerModel; subTicksValue = new LinkedList(); ticksValue = new LinkedList(); spritesList = new LinkedList(); canvasProjection = drawingTools.getTransformationManager().getCanvasProjection(); Vector3d windowTicksDirection = canvasProjection.projectDirection(rulerModel.getTicksDirection()); windowTicksDirection = windowTicksDirection.setZ(0); Vector3d normalizedProjectedTicksDirection = windowTicksDirection.getNormalized(); windowSubTicksDelta = normalizedProjectedTicksDirection.times(rulerModel.getSubTicksLength()); windowTicksDelta = normalizedProjectedTicksDirection.times(rulerModel.getTicksLength()); DecimalFormat format; if (rulerModel.isAutoTicks()) { format = computeAutoGraduation(); } else { format = computeUserGraduation(); } computeTicksData(); draw(drawingTools); double distRatio = computeTicksDistanceRatio(windowTicksDirection.getNorm()); return new RulerDrawingResult(format, ticksValue, subTicksValue, density, distRatio, normalizedProjectedTicksDirection); } /** * Compute the ratio between windows ticks norm and the sprite distance. * @param windowTicksNorm the windows tics norm. * @return the ratio between windows ticks norm and the sprite distance. */ private double computeTicksDistanceRatio(double windowTicksNorm) { double distRatio; if (windowTicksNorm == 0) { distRatio = 1.0; } else if (maximalSpritesDistance == 0) { distRatio = rulerModel.getSpriteDistance() / windowTicksNorm; } else { distRatio = maximalSpritesDistance / windowTicksNorm; } return distRatio; } /** * Actually perform the ruler drawing. * @param drawingTools {@link DrawingTools} used to perform the ruler drawing. */ private synchronized void draw(DrawingTools drawingTools) { BuffersManager bufferManager = drawingTools.getCanvas().getBuffersManager(); ElementsBuffer vertices = bufferManager.createElementsBuffer(); fillVertices(vertices, rulerModel, ticksValue, subTicksValue, canvasProjection); DefaultGeometry geometry = new DefaultGeometry(); geometry.setFillDrawingMode(Geometry.FillDrawingMode.NONE); geometry.setLineDrawingMode(Geometry.LineDrawingMode.SEGMENTS); geometry.setVertices(vertices); Appearance appearance = new Appearance(); appearance.setLineColor(rulerModel.getColor()); appearance.setLineWidth((float) rulerModel.getLineWidth()); drawingTools.getTransformationManager().useWindowCoordinate(); try { for (PositionedSprite positionedSprite : spritesList) { drawingTools.draw(positionedSprite.getSprite(), AnchorPosition.CENTER, positionedSprite.getWindowPosition()); } drawingTools.draw(geometry, appearance); } catch (SciRendererException ignored) { } drawingTools.getTransformationManager().useSceneCoordinate(); bufferManager.dispose(vertices); } /** * Compute the {@link Graduations} used to the ruler drawing in auto-ticks mode.. * @return the used decimal format. */ private DecimalFormat computeAutoGraduation() { /* The maximum distance corresponding to the actually displayed sprites. */ double maxSpritesDistance = 0.0; Graduations currentGraduations = rulerModel.getGraduations(); Graduations ticksGraduation = currentGraduations; DecimalFormat format = currentGraduations.getFormat(); boolean canGetMore = true; List newSpritesList = new LinkedList(); while (currentGraduations != null) { /* The maximum distance to any of the sprites' farthest sides at a given iteration. */ double currentMaximalSpritesDistance = 0; newSpritesList.clear(); List ticks = currentGraduations.getNewValues(); for (double value : ticks) { Texture sprite = computeSprite(value, format); Vector3d windowPosition = canvasProjection.project(rulerModel.getPosition(value)); Dimension textureSize = computeSpriteDimension(value); Vector3d delta = projectCenterToEdge(textureSize, windowTicksDelta); PositionedSprite newSprite = new PositionedSprite(sprite, textureSize, windowPosition.plus(windowTicksDelta.plus(delta))); newSpritesList.add(newSprite); Vector3d farDelta = windowTicksDelta.plus(delta.times(2.0)); currentMaximalSpritesDistance = Math.max(currentMaximalSpritesDistance, farDelta.getNorm()); } if (collide(newSpritesList, rulerModel.getMargin()) || collide(spritesList, newSpritesList, rulerModel.getMargin())) { currentGraduations = currentGraduations.getAlternative(); canGetMore = false; } else { maxSpritesDistance = Math.max(maxSpritesDistance, currentMaximalSpritesDistance); spritesList.addAll(newSpritesList); ticksGraduation = currentGraduations; if (canGetMore) { currentGraduations = currentGraduations.getMore(); } else { currentGraduations = null; } } } this.graduations = ticksGraduation; this.maximalSpritesDistance = maxSpritesDistance; return format; } /** * Compute the {@link Graduations} used to the ruler drawing in auto-ticks mode.. * @return the used decimal format. */ private DecimalFormat computeUserGraduation() { /* The maximum distance corresponding to the actually displayed sprites. */ double maxSpritesDistance = 0.0; Graduations currentGraduations = rulerModel.getGraduations(); List ticks = currentGraduations.getNewValues(); DecimalFormat format = currentGraduations.getFormat(); for (double value : ticks) { Texture sprite = computeSprite(value, format); if (sprite != null) { Vector3d windowPosition = canvasProjection.project(rulerModel.getPosition(value)); Vector3d delta = projectCenterToEdge(sprite, windowTicksDelta); spritesList.add(new PositionedSprite(sprite, windowPosition.plus(windowTicksDelta.plus(delta)))); Vector3d farDelta = windowTicksDelta.plus(delta.times(2.0)); maxSpritesDistance = Math.max(maxSpritesDistance, farDelta.getNorm()); } } this.graduations = currentGraduations; this.maximalSpritesDistance = maxSpritesDistance; return format; } /** * Compute the ticks, sub-ticks data and the sub-ticks density. */ private void computeTicksData() { if (graduations != null) { ticksValue = graduations.getAllValues(); final int N = rulerModel.getSubticksNumber(); if (N < 0) { Graduations subGraduation = graduations.getSubGraduations(); while ((subGraduation != null) && (computeTicksDistance(subGraduation) < rulerModel.getMinimalSubTicksDistance())) { subGraduation = subGraduation.getAlternative(); } if (subGraduation != null) { subTicksValue = subGraduation.getAllValues(); } else { subTicksValue = new LinkedList(); } } else { subTicksValue = graduations.getSubGraduations(N); } density = getDensity(); } else { subTicksValue = new LinkedList(); ticksValue = new LinkedList(); density = 0; } } private int getDensity() { int N = ticksValue == null ? 0 : ticksValue.size(); int M = subTicksValue == null ? 0 : subTicksValue.size(); if (M <= N || N == 1) { return 0; } return (M - N) / (N - 1); } /** * Compute and return the minimal screen distance between two successive ticks of the given {@link Graduations}. * If the given {@link Graduations} is null, the returned value is {@link Double#MAX_VALUE}. * @param graduations the given {@link Graduations}. * @return the minimal screen distance between two successive ticks of the given {@link Graduations}. */ private double computeTicksDistance(Graduations graduations) { double minimalDistance = Double.MAX_VALUE; if (graduations != null) { Vector3d previousProjection = null; for (double currentValue : graduations.getAllValues()) { Vector3d currentProjection = canvasProjection.project(rulerModel.getPosition(currentValue)); if (previousProjection != null) { minimalDistance = Math.min(minimalDistance, currentProjection.minus(previousProjection).getNorm2()); } previousProjection = currentProjection; } minimalDistance = Math.sqrt(minimalDistance); } return minimalDistance; } /** * Return true if at leas two element of {@see spritesList} collide. * @param spritesList the list of sprite to be tested. * @param margin the collision margin. * @return true if at leas two element of {@see spritesList} collide. */ private boolean collide(List spritesList, double margin) { for (int i = 0; i < spritesList.size(); i++) { for (int j = i + 1; j < spritesList.size(); j++) { if (collide(spritesList.get(i).getWindowBounds(), spritesList.get(j).getWindowBounds(), margin)) { return true; } } } return false; } /** * Return true if the at least one element of newSpritesList collides with one element of spritesList. * @param spritesList the list of reference sprites. * @param newSpritesList the list of new sprites. * @param margin the collision margin. * @return true if the at least one element of newSpritesList collides with one element of spritesList. */ private boolean collide(List spritesList, List newSpritesList, double margin) { for (PositionedSprite sprite1 : newSpritesList) { for (PositionedSprite sprite2 : spritesList) { if (collide(sprite1.getWindowBounds(), sprite2.getWindowBounds(), margin)) { return true; } } } return false; } /** * Return true if the givens rectangles collide. * @param rectangle1 first rectangle. * @param rectangle2 second rectangle. * @param margin the margin. * @return true if the givens rectangles collide. */ private boolean collide(Rectangle2D rectangle1, Rectangle2D rectangle2, double margin) { return ((rectangle2.getMinX() - rectangle1.getMaxX()) < margin) && ((rectangle1.getMinX() - rectangle2.getMaxX()) < margin) && ((rectangle2.getMinY() - rectangle1.getMaxY()) < margin) && ((rectangle1.getMinY() - rectangle2.getMaxY()) < margin); } /** * Compute and return a translation along the given direction. * This translation is the vector between the sprite center and is projection along the given * {@see direction} to the sprite edges. * @param sprite the given {@link Texture} * @param direction the given direction. * @return the vector between the sprite center and is projection to the sprite edges. */ private Vector3d projectCenterToEdge(Texture sprite, Vector3d direction) { Vector3d usedDirection; if ((direction == null) || (direction.isZero())) { usedDirection = new Vector3d(1, 0, 0); } else { usedDirection = direction; } /* +1 is used to have a space between the tick and its label */ Dimension textureSize = sprite.getDataProvider().getTextureSize(); double ratioX = textureSize.width / Math.abs(usedDirection.getX()) + 1; double ratioY = textureSize.height / Math.abs(usedDirection.getY()) + 1; double ratio = Math.min(ratioY, ratioX) / 2; return usedDirection.times(ratio); } /** * Compute and return a translation along the given direction. * This translation is the vector between the sprite center and is projection along the given * {@see direction} to the sprite edges. * @param textureSize the size of corresponding texture * @param direction the given direction. * @return the vector between the sprite center and is projection to the sprite edges. */ private Vector3d projectCenterToEdge(Dimension textureSize, Vector3d direction) { Vector3d usedDirection; if ((direction == null) || (direction.isZero())) { usedDirection = new Vector3d(1, 0, 0); } else { usedDirection = direction; } /* +1 is used to have a space between the tick and its label */ double ratioX = textureSize.width / Math.abs(usedDirection.getX()) + 1; double ratioY = textureSize.height / Math.abs(usedDirection.getY()) + 1; double ratio = Math.min(ratioY, ratioX) / 2; return usedDirection.times(ratio); } /** * Fill a vertices buffer with the needed data to draw a ruler. * @param verticesBuffer the {@link ElementsBuffer} to fill. * @param rulerModel the {@link RulerModel} to draw. * @param ticksValue the list of ticks. * @param subTicksValue the list of sub-ticks. * @param canvasProjection the used canvas projection. */ private void fillVertices(ElementsBuffer verticesBuffer, RulerModel rulerModel, List ticksValue, List subTicksValue, Transformation canvasProjection) { Vector3d a = rulerModel.getFirstPoint(); Vector3d b = rulerModel.getSecondPoint(); if ((a != null) && (b != null)) { int bufferSize = 2 * ticksValue.size() + 2 * subTicksValue.size(); if (rulerModel.isLineVisible()) { bufferSize += 2; } FloatBuffer data = FloatBuffer.allocate(4 * bufferSize); data.rewind(); for (double value : ticksValue) { Vector3d p = canvasProjection.project(rulerModel.getPosition(value)); data.put(p.getDataAsFloatArray(4)); data.put(p.plus(windowTicksDelta).getDataAsFloatArray(4)); } for (double value : subTicksValue) { Vector3d p = canvasProjection.project(rulerModel.getPosition(value)); data.put(p.getDataAsFloatArray(4)); data.put(p.plus(windowSubTicksDelta).getDataAsFloatArray(4)); } if (rulerModel.isLineVisible()) { data.put(canvasProjection.project(a).getDataAsFloatArray(4)); data.put(canvasProjection.project(b).getDataAsFloatArray(4)); } data.rewind(); verticesBuffer.setData(data, 4); } else { verticesBuffer.setData(new float[0], 4); } } /** * Compute the {@link Texture} for a given value. * The {@link Texture} is made once using the current {@link RulerSpriteFactory}. * @param value the given value. * @param format the format to use. * @return A {@link Texture} for the label at the given value. */ private Texture computeSprite(double value, DecimalFormat format) { Texture sprite = spriteMap.get(value); if (sprite == null) { sprite = spriteFactory.create(value, format, textureManager); if (sprite != null) { spriteMap.put(value, sprite); } } return sprite; } private Dimension computeSpriteDimension(double value) { Dimension spriteDimension = spriteDimensionMap.get(value); if (spriteDimension == null) { Texture sprite = spriteMap.get(value); if (sprite != null) { spriteDimension = sprite.getDataProvider().getTextureSize(); spriteDimensionMap.put(value, spriteDimension); } } return spriteDimension; } /** * This class is a basic container for a {@link Texture} and an associated window position. * * @author Pierre Lando */ private class PositionedSprite { private final Texture sprite; private final Vector3d windowPosition; private final Rectangle2D windowsBounds; /** * Default constructor. * @param sprite the {@link Texture}. * @param windowPosition the window position. */ public PositionedSprite(Texture sprite, Vector3d windowPosition) { //long tic = Calendar.getInstance().getTimeInMillis(); this.windowPosition = windowPosition; this.sprite = sprite; Dimension textureSize = sprite.getDataProvider().getTextureSize(); windowsBounds = new Rectangle2D.Double( windowPosition.getX(), windowPosition.getY(), textureSize.width, textureSize.height ); //System.err.println("====[new PositionedSprite] time = "+(Calendar.getInstance().getTimeInMillis() - tic)); } public PositionedSprite(Texture sprite, Dimension textureSize, Vector3d windowPosition) { //long tic = Calendar.getInstance().getTimeInMillis(); this.windowPosition = windowPosition; this.sprite = sprite; windowsBounds = new Rectangle2D.Double( windowPosition.getX(), windowPosition.getY(), textureSize.width, textureSize.height ); //System.err.println("====[new PositionedSprite] time = "+(Calendar.getInstance().getTimeInMillis() - tic)); } /** * Return the {@link Texture} * @return the {@link Texture} */ public Texture getSprite() { return sprite; } /** * Return the window position of the {@link Texture}. * @return the window position of the {@link Texture}. */ public Vector3d getWindowPosition() { return windowPosition; } /** * Return the window bounds of the {@link Texture} * @return the window bounds of the {@link Texture} */ public Rectangle2D getWindowBounds() { return windowsBounds; } } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/RulerDrawingResult.java000066400000000000000000000075201212506735300300500ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler; import org.scilab.forge.scirenderer.tranformations.Vector3d; import java.text.DecimalFormat; import java.util.List; /** * Contain information about the ruler drawing result. * * @author Pierre Lando */ public class RulerDrawingResult { /** * Values of drawn ticks. */ private final double[] ticksValues; /** * Values of drawn sub-ticks. */ private final double[] subTicksValues; /** * Sub-ticks density. */ private final int subTicksDensity; /** * The ratio between the maximum distance to any of the sprites' farthest sides * along the projected ticks direction and the projected ticks direction norm. */ private final double maxDistToTicksDirNorm; /** * The normalized projected ticks direction. */ private final Vector3d normalizedTicksDirection; /** The used format to draw sprites */ private final DecimalFormat format; /** * Package constructor. * Those object can only be created by a {@link RulerDrawer} * * @param format * @param ticksValues values of drawn ticks. * @param subTicksValues values of drawn sub-ticks. * @param subTicksDensity sub-ticks density. * @param maxDistToTicksDirNorm the ratio between the maximum sprite distance and the projected ticks direction norm. * @param ticksDir the normalized projected ticks direction. */ RulerDrawingResult(DecimalFormat format, List ticksValues, List subTicksValues, int subTicksDensity, double maxDistToTicksDirNorm, Vector3d ticksDir) { this.format = format; this.ticksValues = listToArray(ticksValues); this.subTicksValues = listToArray(subTicksValues); this.subTicksDensity = subTicksDensity; this.maxDistToTicksDirNorm = maxDistToTicksDirNorm; this.normalizedTicksDirection = new Vector3d(ticksDir); } /** * Format getter * @return the format. */ public DecimalFormat getFormat() { return format; } /** * Convert a list of Double to an array of double. * @param list the given list. * @return an array of double with the value of the given list. */ private double[] listToArray(List list) { double[] array = new double[list.size()]; int index = 0; for (double value : list) { array[index++] = value; } return array; } /** * Drawn ticks values getter. * @return the drawn ticks values. */ public double[] getTicksValues() { return ticksValues.clone(); } /** * Drawn sub-ticks values getter. * @return the drawn sub-ticks values. */ public double[] getSubTicksValues() { return subTicksValues.clone(); } /** * Drawn sub-ticks density getter. * @return the drawn sub-ticks density. */ public int getSubTicksDensity() { return subTicksDensity; } /** * Maximum sprite distance to projected ticks direction norm ratio getter. * @return the distance to ticks direction norm ratio. */ public double getMaxDistToTicksDirNorm() { return maxDistToTicksDirNorm; } /** * Normalized projected ticks direction getter. * @return the normalized projected ticks direction. */ public Vector3d getNormalizedTicksDirection() { return normalizedTicksDirection; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/RulerModel.java000066400000000000000000000110711212506735300263120ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler; import org.scilab.forge.scirenderer.ruler.graduations.Graduations; import org.scilab.forge.scirenderer.shapes.appearance.Color; import org.scilab.forge.scirenderer.tranformations.Vector3d; /** * @author Pierre Lando */ public interface RulerModel { /** * Default first value. */ double DEFAULT_FIRST_VALUE = 0; /** * Default second value. */ double DEFAULT_SECOND_VALUE = 1; /** * Default first point position. */ Vector3d DEFAULT_FIRST_POINT = new Vector3d(0, 0, 0); /** * Default second point position. */ Vector3d DEFAULT_SECOND_POINT = new Vector3d(1, 0, 0); /** * Default margin in pixel. */ double DEFAULT_MARGIN = 12.0; /** * Default main line visibility. */ boolean DEFAULT_LINE_VISIBLE = true; /** * Default {@link org.scilab.forge.scirenderer.sprite.Sprite} distance to the main line in pixel. */ int DEFAULT_SPRITE_DISTANCE = 12; /** * Default sub-tick length in pixel. */ int DEFAULT_SUB_TICK_LENGTH = 5; /** * Default tick length in pixel. */ int DEFAULT_TICK_LENGTH = 10; /** * Default minimal sub-ticks distance. */ double DEFAULT_MINIMAL_SUB_TICKS_DISTANCE = 8; /** * Default auto-ticks status. */ boolean DEFAULT_AUTO_TICKS_STATUS = true; /** * Default logarithmic status. */ boolean DEFAULT_LOGARITHMIC_STATUS = false; /** * Default ticks direction. */ Vector3d DEFAULT_TICKS_DIRECTION = new Vector3d(1, 0, 0); /** * Default color. */ Color DEFAULT_COLOR = new Color(0, 0, 0); /** * Default line width. */ double DEFAULT_LINE_WIDTH = 1.0; /** * Return used graduation to draw this ruler. * @return the used graduation to draw this ruler. */ Graduations getGraduations(); /** * First value getter. * @return the first values. */ double getFirstValue(); /** * Second value getter. * @return the second values. */ double getSecondValue(); /** * First point getter. * @return the first point. */ Vector3d getFirstPoint(); /** * Second point getter. * @return the second point. */ Vector3d getSecondPoint(); /** * Ticks direction getter. * @return the ticks direction. */ Vector3d getTicksDirection(); /** * Ticks length getter. * @return the ticks length in pixel. */ int getTicksLength(); /** * Sub-ticks length getter. * @return the sub-ticks length in pixel. */ int getSubTicksLength(); /** * Return the position corresponding to the given value. * @param value the given value. * @return the position corresponding to the given value. */ Vector3d getPosition(double value); /** * Return the accepted margin (in pixel) for label drawing. * @return the accepted margin (in pixel) for label drawing. */ double getMargin(); /** * Line visibility getter. * @return the line visibility status. */ boolean isLineVisible(); /** * Auto-ticking getter. * @return the auto-ticking status. */ boolean isAutoTicks(); /** * Logarithmic state getter. * @return the logarithmic state */ boolean isLogarithmic(); /** * Sprite distance getter. * @return the sprite distance (in pixel) between the ruler line and the sprites edges. */ int getSpriteDistance(); /** * Minimal accepted sub-ticks distance getter. * @return the minimal accepted sub-ticks distance. */ double getMinimalSubTicksDistance(); /** * Color getter. * @return the color of ruler line and ticks. */ Color getColor(); /** * Line width getter. * @return the line width of ruler line, grid and ticks. */ double getLineWidth(); /** * Number of subticks. * @return the number of subticks or -1 if the computation is automatic. */ int getSubticksNumber(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/RulerSpriteFactory.java000066400000000000000000000020451212506735300300510ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler; import org.scilab.forge.scirenderer.texture.Texture; import org.scilab.forge.scirenderer.texture.TextureManager; import java.text.DecimalFormat; /** * @author Pierre Lando */ public interface RulerSpriteFactory { /** * Return the texture for the given value. * @param value the value. * @param adaptedFormat an adapted number format for the given value. * @param textureManager {@link TextureManager} to use. * @return a positioned text entity for the given value. */ Texture create(double value, DecimalFormat adaptedFormat, TextureManager textureManager); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/graduations/000077500000000000000000000000001212506735300257155ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/graduations/AbstractGraduations.java000066400000000000000000000172201212506735300325260ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler.graduations; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; /** * @author Pierre Lando */ public abstract class AbstractGraduations implements Graduations { /** The left bracket used by {@link #toString()} */ private static final String LEFT_BRACKET = "["; /** The right bracket used by {@link #toString()} */ private static final String RIGHT_BRACKET = "]"; /** True if the lower bound is included in the graduation interval. */ private final boolean isLowerBoundIncluded; /** True if the upper bound is included in the graduation interval. */ private final boolean isUpperBoundIncluded; /** Interval lower bound. */ private final double lowerBound; /** Interval upper bound. */ private final double upperBound; private final Graduations parentGraduations; private DecimalFormat numberFormat; private List subValues; /** * Constructor from parent graduations. * This constructor copy information from given {@link Graduations} and set it as is parent. * @param parentGraduations the parent graduations to copy. */ public AbstractGraduations(Graduations parentGraduations) { this.parentGraduations = parentGraduations; this.isLowerBoundIncluded = parentGraduations.isLowerBoundIncluded(); this.isUpperBoundIncluded = parentGraduations.isUpperBoundIncluded(); this.lowerBound = parentGraduations.getLowerBound(); this.upperBound = parentGraduations.getUpperBound(); } /** * Root constructor. * Graduations made this way don't have a parent. * @param lowerBound the actual lower bounds. * @param lowerBoundIncluded the actual lower bounds included status. * @param upperBound the actual upper bounds. * @param upperBoundIncluded the actual upper bounds included status. */ public AbstractGraduations(double lowerBound, boolean lowerBoundIncluded, double upperBound, boolean upperBoundIncluded) { this.parentGraduations = null; this.isLowerBoundIncluded = lowerBoundIncluded; this.isUpperBoundIncluded = upperBoundIncluded; this.lowerBound = lowerBound; this.upperBound = upperBound; } /** * Root constructor. * Graduations made this way don't have a parent. * There bounds are included. * @param lowerBound the actual lower bounds included status. * @param upperBound the actual upper bounds included status. */ public AbstractGraduations(double lowerBound, double upperBound) { this.parentGraduations = null; this.isLowerBoundIncluded = true; this.isUpperBoundIncluded = true; this.lowerBound = lowerBound; this.upperBound = upperBound; } /** * Child constructor. * @param parentGraduations the parent graduation. * @param lowerBound the actual lower bounds. * @param lowerBoundIncluded the actual lower bounds included status. * @param upperBound the actual upper bounds. * @param upperBoundIncluded the actual upper bounds included status. */ public AbstractGraduations(Graduations parentGraduations, double lowerBound, boolean lowerBoundIncluded, double upperBound, boolean upperBoundIncluded) { this.parentGraduations = parentGraduations; this.isLowerBoundIncluded = lowerBoundIncluded; this.isUpperBoundIncluded = upperBoundIncluded; this.lowerBound = lowerBound; this.upperBound = upperBound; } @Override public final double getLowerBound() { return lowerBound; } @Override public final boolean isLowerBoundIncluded() { return isLowerBoundIncluded; } @Override public final double getUpperBound() { return upperBound; } @Override public final boolean isUpperBoundIncluded() { return isUpperBoundIncluded; } @Override public final Graduations getParentGraduations() { return parentGraduations; } @Override public final boolean contain(double value) { if (value == lowerBound) { return isLowerBoundIncluded; } if (value == upperBound) { return isUpperBoundIncluded; } return (lowerBound < value) && (value < upperBound); } /** * Equivalent to contain but for interval [0, upper-lower] (to avoid rounding error in computations) */ public final boolean containRelative(double value) { if (value == 0) { return isLowerBoundIncluded; } if (value == upperBound - lowerBound || Math.abs(1 - value / (upperBound - lowerBound)) <= 1e-15) { return isUpperBoundIncluded; } return (0 < value) && (value < upperBound - lowerBound); } @Override public final DecimalFormat getFormat() { if (numberFormat == null) { double maxDisplayedValue = Math.max(Math.abs(lowerBound), Math.abs(upperBound)); if ((maxDisplayedValue < 1e-3) || (maxDisplayedValue >= 1e6)) { numberFormat = new DecimalFormat("0.##########E00"); } else if (maxDisplayedValue < 1) { numberFormat = new DecimalFormat("0.######"); } else { numberFormat = new DecimalFormat(); } DecimalFormatSymbols decimalFormatSymbols = numberFormat.getDecimalFormatSymbols(); decimalFormatSymbols.setExponentSeparator("e"); numberFormat.setDecimalFormatSymbols(decimalFormatSymbols); } return numberFormat; } @Override public List getSubGraduations(final int N) { if (subValues == null) { List ticksValue = getAllValues(); if (N == 0 || ticksValue.size() == 0) { subValues = new LinkedList(); } else { Collections.sort(ticksValue); subValues = new LinkedList(); for (int i = 0; i < ticksValue.size() - 1; i++) { final double first = ticksValue.get(i); final double second = ticksValue.get(i + 1); final double step = (second - first) / (N + 1); double v = first; for (int j = 0; j <= N; j++) { subValues.add(v); v += step; } } subValues.add(ticksValue.get(ticksValue.size() - 1)); } } return subValues; } @Override public final String toString() { String lowerBoundBracket; String upperBoundBracket; if (isLowerBoundIncluded) { lowerBoundBracket = LEFT_BRACKET; } else { lowerBoundBracket = RIGHT_BRACKET; } if (isUpperBoundIncluded) { upperBoundBracket = RIGHT_BRACKET; } else { upperBoundBracket = LEFT_BRACKET; } return "Graduation " + lowerBoundBracket + getFormat().format(lowerBound) + ", " + getFormat().format(upperBound) + upperBoundBracket; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/graduations/Graduations.java000066400000000000000000000054361212506735300310500ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler.graduations; import java.text.DecimalFormat; import java.util.List; /** * @author Pierre Lando */ public interface Graduations { /** * Return the lower bound. * @return the lower bound. */ double getLowerBound(); /** * Return true if the lower bound is included. * @return true if the lower bound is included. */ boolean isLowerBoundIncluded(); /** * Return the upper bound. * @return the upper bound. */ double getUpperBound(); /** * Return true if the lower bound is included. * @return true if the lower bound is included. */ boolean isUpperBoundIncluded(); /** * Return true if the interval contain the given value. * @param value the given value. * @return true if the interval contain the given value. */ boolean contain(double value); /** * Return an adapted number format. * @return an adapted number format. */ DecimalFormat getFormat(); /** * Return all values of this graduation. * @return all values of this graduation. */ List getAllValues(); /** * Return values not present in parents graduations. * @return values not present in parents graduations. */ List getNewValues(); /** * Return the parent graduation. * @return the parent graduation. */ Graduations getParentGraduations(); /** * Return a child graduation with more values. * @return a child graduation with more values. */ Graduations getMore(); /** * Return a child graduation with more values but less than getMore() * @return a child graduation with more values but less than getMore() */ Graduations getAlternative(); /** * Return a child graduation for sub ticks. * @return a child graduation for sub ticks. */ Graduations getSubGraduations(); /** * Get the list of subgraduations corresponding to N subticks between two main consecutives ticks * @param N the number of graduations * @return the corresponding list */ List getSubGraduations(int N); /** * Return the density of sub ticks. * @return the density of sub ticks. */ int getSubDensity(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/graduations/LinearGraduations.java000066400000000000000000000172241212506735300322010ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler.graduations; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; /** * A linear graduation is a graduation with regular spaces mark. * The mark distance is called "Step" and have for value {@code mantissa x 10^exponent}. * Where mantissa is 1, 2 or 5. * Exponent is an integer. * * @author Pierre Lando */ public final class LinearGraduations extends AbstractGraduations implements Graduations { /** * The step exponent. */ protected final int stepExponent; /** * The step mantissa. */ protected final int stepMantissa; private LinearGraduations moreGraduation; private LinearGraduations alternativeGraduation; private Graduations subGraduation; private Double stepValue; private List allValues; private List newValues; /** * Private constructor. * Use creates methods. */ private LinearGraduations() { super(null); stepExponent = 0; stepMantissa = 0; } private LinearGraduations(Graduations parentGraduations, int stepExponent, int stepMantissa) { super(parentGraduations); this.stepExponent = stepExponent; this.stepMantissa = stepMantissa; } private LinearGraduations(Graduations parentGraduations, double lowerBound, boolean lowerBoundIncluded, double upperBound, boolean upperBoundIncluded) { super(parentGraduations, lowerBound, lowerBoundIncluded, upperBound, upperBoundIncluded); if (lowerBound != upperBound) { double size = upperBound - lowerBound; stepExponent = (int) Math.ceil(Math.log10(size)); stepMantissa = 1; } else { stepExponent = 0; stepMantissa = 0; newValues = new LinkedList(); allValues = new LinkedList(); allValues.add(lowerBound); } } public static LinearGraduations create(double lowerBound, double upperBound) { return create(lowerBound, true, upperBound, true); } public static LinearGraduations create( Graduations parentGraduations, double lowerBound, boolean lowerBoundIncluded, double upperBound, boolean upperBoundIncluded ) { if (lowerBound < upperBound) { return new LinearGraduations(parentGraduations, lowerBound, lowerBoundIncluded, upperBound, upperBoundIncluded); } else { return new LinearGraduations(parentGraduations, upperBound, upperBoundIncluded, lowerBound, lowerBoundIncluded); } } public static LinearGraduations create(double lowerBound, boolean lowerBoundIncluded, double upperBound, boolean upperBoundIncluded) { if (lowerBound < upperBound) { return new LinearGraduations(null, lowerBound, lowerBoundIncluded, upperBound, upperBoundIncluded); } else { return new LinearGraduations(null, upperBound, upperBoundIncluded, lowerBound, lowerBoundIncluded); } } private Double getStepValue() { if (stepValue == null) { stepValue = stepMantissa * Math.pow(10, stepExponent); } return stepValue; } private boolean isNewIndex(long index) { /* We are now searching for value look like * index * (stepMantissa * 10^n) and we don't want (previousStrepMantissa * 10^k) value. */ if (stepMantissa == 1) { // (5 * index * stepMantissa) % 10 != 0 return (index % 2 != 0); } else if (stepMantissa == 2) { // (2 * index * stepMantissa) % 10 != 0 return (index % 5 != 0); } else { // (5 * index * stepMantissa) % 10 != 0 return ((index * stepMantissa) % 2 != 0); } } @Override public List getNewValues() { if (getParentGraduations() == null) { return getAllValues(); } if (newValues == null) { newValues = new LinkedList(); final double lb = getLowerBound(); long currentIndex = (long) Math.ceil(lb / getStepValue()); double currentValue = getStepValue() * currentIndex; double value = currentValue - lb; if (value == 0 && (!containRelative(value))) { value += getStepValue(); currentIndex++; } while (containRelative(value) && !Double.isInfinite(lb + value)) { if (isNewIndex(currentIndex)) { newValues.add(lb + value); } value += getStepValue(); currentIndex++; } } return newValues; } @Override public List getAllValues() { if (allValues == null) { final double lb = getLowerBound(); allValues = new LinkedList(); double currentValue = getStepValue() * Math.ceil(lb / getStepValue()); double value = currentValue - lb; if (value == 0 && !containRelative(value)) { value += getStepValue(); } while (containRelative(value) && !Double.isInfinite(lb + value)) { allValues.add(lb + value); value += getStepValue(); } } return allValues; } @Override public LinearGraduations getMore() { if (stepMantissa != 5) { if (moreGraduation == null) { if (stepMantissa == 1) { moreGraduation = new LinearGraduations(this, stepExponent - 1, 2); } else { moreGraduation = new LinearGraduations(this, stepExponent, 1); } } return moreGraduation; } else { return null; } } @Override public LinearGraduations getAlternative() { if (stepMantissa == 2) { if (alternativeGraduation == null) { if (getParentGraduations() == null) { alternativeGraduation = new LinearGraduations(null, getLowerBound(), true, getLowerBound(), true); } else { alternativeGraduation = new LinearGraduations(getParentGraduations(), stepExponent, 5); } } return alternativeGraduation; } else { return null; } } @Override public Graduations getSubGraduations() { if (subGraduation == null) { switch (stepMantissa) { case 1: subGraduation = new LinearGraduations(this, stepExponent - 1, 5); break; case 2: subGraduation = new LinearGraduations(this, stepExponent, 1); break; case 5: subGraduation = new LinearGraduations(getParentGraduations(), stepExponent, 1); break; default: subGraduation = null; break; } } return subGraduation; } @Override public int getSubDensity() { if (stepMantissa == 5) { return 5; } else { return 2; } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/ruler/graduations/LogarithmicGraduations.java000066400000000000000000000255231212506735300332320ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.ruler.graduations; import java.util.LinkedList; import java.util.List; /** * @author Pierre Lando */ public final class LogarithmicGraduations extends AbstractGraduations implements Graduations { /** * Exponent of the step. * Possible value are : 1, 2 and 3*k with k > 0 */ private final int stepExponent; private List allValues; private Graduations subGraduation; private Graduations moreGraduation; private Graduations alternativeGraduation; /** * Private child constructor. * The interval is copied from parent's one. * @param parentGraduations the parent graduation. * @param stepExponent the step exponent. */ private LogarithmicGraduations(Graduations parentGraduations, int stepExponent) { super(parentGraduations); this.stepExponent = stepExponent; } /** * Private root graduation constructor. * This graduation has no parent. * @param lowerBound actual lower bound. * @param lowerBoundIncluded true if the lower bound is included in the interval. * @param upperBound actual upper bound. * @param upperBoundIncluded true if the upper bound is included in the interval. */ private LogarithmicGraduations(double lowerBound, boolean lowerBoundIncluded, double upperBound, boolean upperBoundIncluded) { super(lowerBound, lowerBoundIncluded, upperBound, upperBoundIncluded); if (lowerBound != upperBound) { stepExponent = 1; } else { stepExponent = 0; allValues = new LinkedList(); allValues.add(lowerBound); } } public static LogarithmicGraduations create(double lowerBound, double upperBound) { return create(lowerBound, true, upperBound, true); } public static LogarithmicGraduations create(double lowerBound, boolean lowerBoundIncluded, double upperBound, boolean upperBoundIncluded) { if (lowerBound < upperBound) { return new LogarithmicGraduations(lowerBound, lowerBoundIncluded, upperBound, upperBoundIncluded); } else { return new LogarithmicGraduations(upperBound, upperBoundIncluded, lowerBound, lowerBoundIncluded); } } @Override public List getAllValues() { if (allValues == null) { allValues = new LinkedList(); int currentExponent = (int) Math.ceil(Math.log10(getLowerBound())); double currentValue = Math.pow(10, currentExponent); final double step = Math.pow(10, stepExponent); if ((currentValue == getLowerBound()) && (!isLowerBoundIncluded())) { currentValue *= step; } while (contain(currentValue) && !Double.isInfinite(currentValue)) { allValues.add(currentValue); currentValue *= step; } } return allValues; } @Override public List getNewValues() { return getAllValues(); } @Override public Graduations getMore() { if (moreGraduation == null) { moreGraduation = new LinLogGraduation(this); } return moreGraduation; } @Override public Graduations getAlternative() { if (alternativeGraduation == null) { int nextStep = 3 + stepExponent - stepExponent % 3; alternativeGraduation = new LogarithmicGraduations(this, nextStep); } return alternativeGraduation; } @Override public Graduations getSubGraduations() { if (subGraduation == null) { if (stepExponent > 1) { subGraduation = new LogarithmicGraduations(this, stepExponent / 3); } else { subGraduation = new LinLogGraduation(this).getSubGraduations(); } } return subGraduation; } @Override public int getSubDensity() { if (stepExponent >= 3) { return 3; } else if (stepExponent == 2) { return stepExponent; } else { return getSubGraduations().getSubDensity(); } } /** * This class manage linear graduation between 10^n and 10^(n+1) */ private class LinLogGraduation extends AbstractGraduations implements Graduations { private Graduations alternativeLLGraduation; private Graduations moreLLGraduation; private Graduations subLLGraduation; private List allValues; private List newValues; private final List graduationsList; public LinLogGraduation(LogarithmicGraduations parentGraduations) { super(parentGraduations); graduationsList = computeGraduationsList(); } private LinLogGraduation(Graduations parentGraduations, List graduationsList) { super(parentGraduations); this.graduationsList = graduationsList; } @Override public List getAllValues() { if (allValues == null) { allValues = new LinkedList(); for (Graduations graduations : graduationsList) { allValues.addAll(graduations.getAllValues()); } allValues.addAll(getLogarithmicParent().getAllValues()); } return allValues; } @Override public List getNewValues() { if (newValues == null) { newValues = new LinkedList(); if (getParentGraduations() instanceof LogarithmicGraduations) { for (Graduations graduations : graduationsList) { newValues.addAll(graduations.getAllValues()); } } else { for (Graduations graduations : graduationsList) { newValues.addAll(graduations.getNewValues()); } } } return newValues; } @Override public Graduations getMore() { if (moreLLGraduation == null) { List moreList = new LinkedList(); for (Graduations graduations : graduationsList) { Graduations more = graduations.getMore(); if (more != null) { moreList.add(more); } } if (!moreList.isEmpty()) { moreLLGraduation = new LinLogGraduation(this, moreList); } } return moreLLGraduation; } @Override public Graduations getAlternative() { if (alternativeLLGraduation == null) { List alternativeList = new LinkedList(); for (Graduations graduations : graduationsList) { Graduations alternative = graduations.getAlternative(); if (alternative != null) { alternativeList.add(alternative); } } if (!alternativeList.isEmpty()) { alternativeLLGraduation = new LinLogGraduation(this, alternativeList); } } return alternativeLLGraduation; } @Override public Graduations getSubGraduations() { if (subLLGraduation == null) { List subList = new LinkedList(); for (Graduations graduations : graduationsList) { Graduations sub = graduations.getSubGraduations(); if (sub != null) { subList.add(sub); } } if (subList.isEmpty()) { subLLGraduation = getMore().getSubGraduations(); } else { subLLGraduation = new LinLogGraduation(this, subList); } } return subLLGraduation; } @Override public int getSubDensity() { return 0; } private List computeGraduationsList() { List list = new LinkedList(); /** * Let a and b a power of 10. * lowerBound < a < b < upperBound */ double aPower = Math.ceil(Math.log10(getLowerBound())); double bPower = Math.floor(Math.log10(getUpperBound())); double a = Math.pow(10, aPower); double b = Math.pow(10, bPower); if (aPower > bPower) { // Case of 10^n <= a < b <= 10^(n+1) list.add(LinearGraduations.create( this, getLowerBound(), true, getUpperBound(), true )); } else { if (a != getLowerBound()) { list.add(LinearGraduations.create( this, getLowerBound(), true, a, false )); } if (aPower != bPower) { // Limit iterations on power smaller than 10^310 (Max double ~ 10^308) for (double i = aPower; i < Math.min(bPower, 310); i++) { list.add(LinearGraduations.create( this, Math.pow(10, i), false, Math.pow(10, i + 1), false )); } } if (b != getUpperBound()) { list.add(LinearGraduations.create( this, b, false, getUpperBound(), true )); } } return list; } private Graduations getLogarithmicParent() { Graduations currentGraduation = getParentGraduations(); while (!(currentGraduation instanceof LogarithmicGraduations)) { currentGraduation = currentGraduation.getParentGraduations(); } return currentGraduation; } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/shapes/000077500000000000000000000000001212506735300235275ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/shapes/appearance/000077500000000000000000000000001212506735300256265ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/shapes/appearance/Appearance.java000066400000000000000000000072041212506735300305330ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.shapes.appearance; import org.scilab.forge.scirenderer.texture.Texture; /** * * Basic class for appearance parameters. * * @author Pierre Lando */ public final class Appearance { /** * The default line width. */ public static final float DEFAULT_LINE_WIDTH = 1.0f; /** * The default line pattern (full line). * The 16 bits of the pattern represents how lines are drawn. */ public static final short DEFAULT_LINE_PATTERN = (short) 0xFFFF; /** * The default line color. */ public static final Color DEFAULT_LINE_COLOR = new Color(.8f, .8f, .8f); /** * The default fill color. */ public static final Color DEFAULT_FILL_COLOR = new Color(.8f, .8f, .8f); /** * Current {@link Texture} */ private Texture texture; /** * The current line width. */ private float lineWidth = DEFAULT_LINE_WIDTH; /** * The current line pattern. * The 16 bits of the pattern represents how lines are drawn. */ private short linePattern = DEFAULT_LINE_PATTERN; /** * the current line color. */ private Color lineColor = DEFAULT_LINE_COLOR; /** * The current fill color. */ private Color fillColor = DEFAULT_FILL_COLOR; /** * Default constructor. */ public Appearance() { } /** * Return the default appearance. * @return the default appearance. */ public static Appearance getDefault() { return new Appearance(); } /** * Texture getter. * @return the current texture if any. */ public Texture getTexture() { if ((texture != null) && (texture.isValid())) { return texture; } else { return null; } } /** * Texture setter. * @param texture the new texture. */ public void setTexture(Texture texture) { this.texture = texture; } /** * Return the line width. * @return the line width. */ public float getLineWidth() { return lineWidth; } /** * Set the line width. * @param lineWidth the new line width. */ public void setLineWidth(float lineWidth) { this.lineWidth = lineWidth; } /** * Return the line pattern. * @return the line pattern. */ public short getLinePattern() { return linePattern; } /** * Set the line pattern. * @param linePattern the new line pattern. */ public void setLinePattern(short linePattern) { this.linePattern = linePattern; } /** * Return the line color. * @return the line color. */ public Color getLineColor() { return lineColor; } /** * Set the line color. * @param lineColor the new lne color. */ public void setLineColor(Color lineColor) { this.lineColor = lineColor; } /** * Return the fill color. * @return the fill color. */ public Color getFillColor() { return fillColor; } /** * Set the fill color. * @param fillColor the new fill color. */ public void setFillColor(Color fillColor) { this.fillColor = fillColor; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/shapes/appearance/Color.java000066400000000000000000000057431212506735300275600ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.shapes.appearance; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public final class Color extends java.awt.Color { private static final float COMPONENT_MAX_VALUE = 255f; /** * The default color. */ private static final Color DEFAULT_COLOR = new Color(.2f, .3f, .4f); /** * Default constructor. * Create a copy of the default color. */ public Color() { this(DEFAULT_COLOR); } /** * Copy constructor * @param c the color to copy. */ public Color(Color c) { super(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); } /** * Creates an sRGB color with the specified red, green, blue, and * alpha values in the range [0.0; 1.0]. The actual color * used in rendering depends on finding the best match given the * color space available for a particular output device. * * @param r the red component * @param g the green component * @param b the blue component * @param a the alpha component */ public Color(float r, float g, float b, float a) { super(r, g, b, a); } /** * Creates an opaque sRGB color with the specified red, green, and blue * values in the range [0.0; 1.0]. Alpha is defaulted to 1.0. The * actual color used in rendering depends on finding the best * match given the color space available for a particular output * device. * * @param r the red component * @param g the green component * @param b the blue component */ public Color(float r, float g, float b) { super(r, g, b); } /** * Return red component value. In the range [0; 1]. * @return red component value. In the range [0; 1]. */ public float getRedAsFloat() { return ((float) getRed()) / COMPONENT_MAX_VALUE; } /** * Return green component value. In the range [0; 1]. * @return green component value. In the range [0; 1]. */ public float getGreenAsFloat() { return ((float) getGreen()) / COMPONENT_MAX_VALUE; } /** * Return blue component value. In the range [0; 1]. * @return blue component value. In the range [0; 1]. */ public float getBlueAsFloat() { return ((float) getBlue()) / COMPONENT_MAX_VALUE; } /** * Return alpha component value. In the range [0; 1]. * @return alpha component value. In the range [0; 1]. */ public float getAlphaAsFloat() { return ((float) getAlpha()) / COMPONENT_MAX_VALUE; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/shapes/geometry/000077500000000000000000000000001212506735300253625ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/shapes/geometry/DefaultGeometry.java000066400000000000000000000107471212506735300313360ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.shapes.geometry; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; /** * * Default implementation of a Geometry. * * @author Pierre Lando */ public class DefaultGeometry implements Geometry { private FaceCullingMode faceCullingMode = DEFAULT_FACE_CULLING_MODE; private FillDrawingMode fillDrawingMode = DEFAULT_FILL_DRAWING_MODE; private LineDrawingMode lineDrawingMode = DEFAULT_LINE_DRAWING_MODE; /** Specifies whether polygon offset is used or not when rendering geometry. */ private boolean polygonOffsetMode = DEFAULT_POLYGON_OFFSET_MODE; private ElementsBuffer textureCoordinates; private ElementsBuffer vertices; private ElementsBuffer normals; private ElementsBuffer colors; private IndicesBuffer wireIndices; private IndicesBuffer indices; /** * Default constructor. */ public DefaultGeometry() { } @Override public final FaceCullingMode getFaceCullingMode() { return faceCullingMode; } @Override public final FillDrawingMode getFillDrawingMode() { return fillDrawingMode; } @Override public final LineDrawingMode getLineDrawingMode() { return lineDrawingMode; } @Override public final boolean getPolygonOffsetMode() { return polygonOffsetMode; } @Override public final ElementsBuffer getVertices() { return vertices; } @Override public final IndicesBuffer getIndices() { return indices; } @Override public final IndicesBuffer getWireIndices() { return wireIndices; } @Override public final ElementsBuffer getColors() { return colors; } @Override public final ElementsBuffer getTextureCoordinates() { return textureCoordinates; } @Override public final ElementsBuffer getNormals() { return normals; } /** * Face culling mode setter. * @param faceCullingMode the new face culling mode. */ public final void setFaceCullingMode(FaceCullingMode faceCullingMode) { this.faceCullingMode = faceCullingMode; } /** * Fill drawing mode setter. * @param fillDrawingMode the new fill drawing mode. */ public final void setFillDrawingMode(FillDrawingMode fillDrawingMode) { this.fillDrawingMode = fillDrawingMode; } /** * Line drawing mode setter. * @param lineDrawingMode the new line drawing mode. */ public final void setLineDrawingMode(LineDrawingMode lineDrawingMode) { this.lineDrawingMode = lineDrawingMode; } /** * Polygon offset mode setter. * @param polygonOffsetMode the new polygon offset mode. */ public final void setPolygonOffsetMode(boolean polygonOffsetMode) { this.polygonOffsetMode = polygonOffsetMode; } /** * Texture coordinates setter. * @param textureCoordinates the new texture coordinate data. */ public final void setTextureCoordinates(ElementsBuffer textureCoordinates) { this.textureCoordinates = textureCoordinates; } /** * Vertices setter. * @param vertices the new vertices data. */ public final void setVertices(ElementsBuffer vertices) { this.vertices = vertices; } /** * Normals setter. * @param normals the new normals data. */ public final void setNormals(ElementsBuffer normals) { this.normals = normals; } /** * Colors setter. * @param colors the new colors data. */ public final void setColors(ElementsBuffer colors) { this.colors = colors; } /** * Wire indices setter. * @param wireIndices the new wire indices data. */ public final void setWireIndices(IndicesBuffer wireIndices) { this.wireIndices = wireIndices; } /** * Indices setter. * @param indicesBuffer the new indices data. */ public final void setIndices(IndicesBuffer indicesBuffer) { this.indices = indicesBuffer; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/shapes/geometry/Geometry.java000066400000000000000000000074751212506735300300350ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.shapes.geometry; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; /** * * Interface for a geometry. * * @author Pierre Lando */ public interface Geometry { /** * This enum specify face culling. */ enum FaceCullingMode { /** * Both faces are rendered (default value) */ BOTH, /** * Only counter clockwise faces are visible. */ CCW, /** * Only clockwise faces are visible. */ CW } /** * Default face culling mode. */ FaceCullingMode DEFAULT_FACE_CULLING_MODE = FaceCullingMode.BOTH; /** * This enum specify how geometry is rendered. */ enum FillDrawingMode { /** * Treats each triplet of vertices as an independent triangle. */ TRIANGLES, /** * Draws a connected group of triangles. */ TRIANGLE_STRIP, /** * Draws a connected group of triangles with common first element. */ TRIANGLE_FAN, /** * Nothing is filled. */ NONE } /** * Default fill drawing mode. */ FillDrawingMode DEFAULT_FILL_DRAWING_MODE = FillDrawingMode.TRIANGLES; /** * Line drawing modes declaration. */ enum LineDrawingMode { /** * Each pair of vertices define an independent segment. */ SEGMENTS, /** * Connected group of segments from the first vertex to the last. */ SEGMENTS_STRIP, /** * Connected group of segments from the first vertex to the last, then back to the first. */ SEGMENTS_LOOP, /** * No segments. */ NONE } /** * Default wire drawing mode. */ LineDrawingMode DEFAULT_LINE_DRAWING_MODE = LineDrawingMode.NONE; /** * Default polygon offset mode. */ boolean DEFAULT_POLYGON_OFFSET_MODE = false; /** * Face-culling mode getter. * @return the face culling mode. */ FaceCullingMode getFaceCullingMode(); /** * Fill drawing mode getter. * @return the fill-drawing mode for this object. */ FillDrawingMode getFillDrawingMode(); /** * Line drawing mode getter. * @return the line drawing mode. */ LineDrawingMode getLineDrawingMode(); /** * Polygon offset mode getter. * @return the polygon offset mode. */ boolean getPolygonOffsetMode(); /** * Return the vertices. * @return the vertices. */ ElementsBuffer getVertices(); /** * Return the colors. * @return the colors. */ ElementsBuffer getColors(); /** * Texture coordinates getter. * @return the texture coordinate. */ ElementsBuffer getTextureCoordinates(); /** * Return the normals. * @return the normals. */ ElementsBuffer getNormals(); /** * Return the indices if any. * If null is returned, indices should be treated as consecutive number. * @return the indices. */ IndicesBuffer getIndices(); /** * Return the wire indices. * If null is returned, no edges are drawn. * @return the edges indices. */ IndicesBuffer getWireIndices(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/000077500000000000000000000000001212506735300237445ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/AbstractTexture.java000066400000000000000000000060111212506735300277310ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; /** * @author Pierre Lando */ public class AbstractTexture implements Texture { /** * Texture data provider. */ protected TextureDataProvider textureDataProvider; /** * True if the data are up to date. */ protected boolean upToDate; /** * Current magnification filtering method. */ private Filter magnificationFilter = Filter.NEAREST; /** * Current minifying filtering method. */ private Filter minifyingFilter = Filter.NEAREST; private Wrap sWrappingMode = Wrap.CLAMP; private Wrap tWrappingMode = Wrap.CLAMP; /** * Default constructor. */ public AbstractTexture() { upToDate = false; } @Override public synchronized boolean isValid() { return (textureDataProvider != null) && (textureDataProvider.isValid()); } @Override public Wrap getSWrappingMode() { return sWrappingMode; } @Override public void setSWrappingMode(Wrap sWrappingMode) { this.sWrappingMode = sWrappingMode; } @Override public Wrap getTWrappingMode() { return tWrappingMode; } @Override public void setTWrappingMode(Wrap tWrappingMode) { this.tWrappingMode = tWrappingMode; } @Override public Filter getMinifyingFilter() { return minifyingFilter; } @Override public void setMinifyingFilter(Filter minifyingFilter) { this.minifyingFilter = minifyingFilter; } @Override public Filter getMagnificationFilter() { return magnificationFilter; } @Override public void setMagnificationFilter(Filter magnificationFilter) { this.magnificationFilter = magnificationFilter; } @Override public synchronized TextureDataProvider getDataProvider() { return textureDataProvider; } @Override public synchronized void setDataProvider(TextureDataProvider provider) { if (textureDataProvider != null) { textureDataProvider.removeDataUser(this); } textureDataProvider = provider; upToDate = false; if (textureDataProvider != null) { textureDataProvider.addDataUser(this); } } @Override public void setDrawer(TextureDrawer textureDrawer) { setDataProvider(new DrawnTextureDataProvider(textureDrawer)); } @Override public void dataUpdated() { upToDate = false; } @Override public double getSScaleFactor() { return 1; } @Override public double getTScaleFactor() { return 1; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/AbstractTextureDataProvider.java000066400000000000000000000035141212506735300322430ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; import org.scilab.forge.scirenderer.data.AbstractDataProvider; /** * @author Calixte DENIZET */ public abstract class AbstractTextureDataProvider extends AbstractDataProvider implements TextureDataProvider { @Override public BufferedImage getImage() { final ByteBuffer data = getData(); if (data == null) { return null; } data.rewind(); Dimension size = getTextureSize(); final int width = size.width; final int height = size.height; final int[] ibuffer = new int[data.capacity() / 4]; final byte[] RGBA = new byte[4]; for (int i = 0; i < ibuffer.length; i++) { data.get(RGBA); ibuffer[i] = ((RGBA[3] & 0xFF) << 24) + ((RGBA[0] & 0xFF) << 16) + ((RGBA[1] & 0xFF) << 8) + (RGBA[2] & 0xFF); } data.rewind(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); image.setRGB(0, 0, width, height, ibuffer, 0, width); return image; } @Override public BufferedImage getSubImage(int x, int y, int width, int height) { BufferedImage image = getImage(); if (image == null) { return null; } return image.getSubimage(x, y, width, height); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/AnchorPosition.java000066400000000000000000000025051212506735300275500ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; /** * This is an enumeration of possible sprite anchor position. * @author Pierre Lando */ public enum AnchorPosition { /** * Anchor is in the upper left sprite corner. */ UPPER_LEFT, /** * Anchor is in the upper right sprite corner. */ UPPER_RIGHT, /** * Anchor is in the lower left sprite corner. */ LOWER_LEFT, /** * Anchor is in the lower right sprite corner. */ LOWER_RIGHT, /** * Anchor is in the sprite center. */ CENTER, /** * Anchor is in the center of the right edge of the sprite. */ RIGHT, /** * Anchor is in the center of the left edge of the sprite. */ LEFT, /** * Anchor is in the center of the down edge of the sprite. */ DOWN, /** * Anchor is in the center of the upper edge of the sprite. */ UP, } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/BufferedImageTextureDrawingTools.java000066400000000000000000000161111212506735300332120ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import org.scilab.forge.scirenderer.implementation.jogl.utils.G2DShortCuts; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import javax.swing.Icon; import javax.swing.JLabel; import java.awt.AlphaComposite; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; /** * * Implementation of {@link org.scilab.forge.scirenderer.texture.TextureDrawingTools}. * This implementation create a {@link TextureBufferedImage} an fill it with texture drawing. * * @author Pierre Lando */ public class BufferedImageTextureDrawingTools implements TextureDrawingTools { /** * The {@link Graphics2D} used to fill the {@link TextureBufferedImage} */ private Graphics2D g2d; private final TextureBufferedImage image; private final Dimension textureSize; private final AffineTransform baseTransform; /** * Default constructor. * @param textureSize the texture size. */ public BufferedImageTextureDrawingTools(Dimension textureSize) { image = new TextureBufferedImage(textureSize.width, textureSize.height); this.textureSize = textureSize; double deltaW = (image.getWidth() - textureSize.width) / 2.0; double deltaH = (image.getHeight() - textureSize.height) / 2.0; baseTransform = AffineTransform.getTranslateInstance(deltaW, deltaH); } /** * Ask this image to accept a texture drawer. * This image will contain the drawing of the given drawer. * @param textureDrawer the given texture drawer. */ public void accept(TextureDrawer textureDrawer) { g2d = image.createGraphics(); g2d.setComposite(AlphaComposite.Src); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.transform(baseTransform); // Change center coordinate to (0, 0). if (textureDrawer.getOriginPosition() == TextureDrawer.OriginPosition.CENTER) { g2d.translate(textureSize.width / 2, textureSize.height / 2); } textureDrawer.draw(this); g2d.dispose(); } @Override public void drawPlus(int size, Appearance appearance) { int r = size / 2; int[] coords1 = new int[]{-r, 0, r, 0}; int[] coords2 = new int[]{0, -r, 0, r}; drawPolyline(coords1, appearance); drawPolyline(coords2, appearance); } @Override public void drawPolyline(int[] coordinates, Appearance appearance) { int nbPoint = coordinates.length / 2; int[] xCoordinates = new int[nbPoint]; int[] yCoordinates = new int[nbPoint]; int k = 0; for (int i = 0; i < coordinates.length; i += 2) { xCoordinates[k] = coordinates[i]; yCoordinates[k] = coordinates[i + 1]; k++; } G2DShortCuts.useLineAppearance(g2d, appearance); G2DShortCuts.useColor(g2d, appearance.getLineColor()); g2d.drawPolyline(xCoordinates, yCoordinates, nbPoint); } @Override public void fillPolygon(int[] coordinates, Appearance appearance) { int nbPoint = coordinates.length / 2; int[] xCoordinates = new int[nbPoint]; int[] yCoordinates = new int[nbPoint]; int k = 0; for (int i = 0; i < coordinates.length; i += 2) { xCoordinates[k] = coordinates[i]; yCoordinates[k] = coordinates[i + 1]; k++; } if (appearance.getFillColor().getAlphaAsFloat() != 0) { G2DShortCuts.useColor(g2d, appearance.getFillColor()); g2d.fillPolygon(xCoordinates, yCoordinates, nbPoint); } if (!appearance.getLineColor().equals(appearance.getFillColor())) { int usedLength = coordinates.length - (coordinates.length % 2); int[] borderCoordinate = new int[usedLength + 2]; System.arraycopy(coordinates, 0, borderCoordinate, 0, usedLength); borderCoordinate[usedLength] = coordinates[0]; borderCoordinate[usedLength + 1] = coordinates[1]; drawPolyline(borderCoordinate, appearance); } } @Override public void drawCircle(int x, int y, int diameter, Appearance appearance) { G2DShortCuts.useLineAppearance(g2d, appearance); G2DShortCuts.useColor(g2d, appearance.getLineColor()); int r = diameter / 2; g2d.drawOval(x - r, y - r, diameter, diameter); } @Override public void fillDisc(int x, int y, int diameter, Color color) { if (color.getAlphaAsFloat() != 0) { G2DShortCuts.useColor(g2d, color); int r = diameter / 2; g2d.fillOval(x - r, y - r, diameter, diameter); } } @Override public void draw(TextEntity textEntity, int x, int y) { if ((textEntity != null) && (textEntity.isValid())) { if (textEntity.isTextAntiAliased()) { g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); } else { g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); } if (textEntity.isTextUseFractionalMetrics()) { g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); } else { g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF); } g2d.setColor(textEntity.getTextColor()); TextLayout textLayout = new TextLayout(textEntity.getText(), textEntity.getFont(), g2d.getFontRenderContext()); Rectangle2D bounds = textLayout.getBounds(); textLayout.draw(g2d, (float) (x + 1 - bounds.getX()), (float) (y + 1 - bounds.getY())); } } @Override public void draw(Icon icon, int x, int y) { icon.paintIcon(new JLabel(), g2d, x, y); } @Override public void clear(Color color) { AffineTransform oldTransform = g2d.getTransform(); g2d.setTransform(baseTransform); G2DShortCuts.useColor(g2d, color); g2d.fillRect(0, 0, textureSize.width, textureSize.height); g2d.setTransform(oldTransform); } /** * Return the image. * @return the image. */ public TextureBufferedImage getImage() { return image; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/DrawnTextureDataProvider.java000066400000000000000000000063641212506735300315610ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import org.scilab.forge.scirenderer.data.AbstractDataProvider; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; /** * @author Pierre Lando */ public class DrawnTextureDataProvider extends AbstractDataProvider implements TextureDataProvider { /** Texture drawer */ private TextureDrawer textureDrawer; /** Current image */ BufferedImageTextureDrawingTools image; public DrawnTextureDataProvider(TextureDrawer textureDrawer) { this.textureDrawer = textureDrawer; //reDraw(); } /** Reload the texture and recall the texture drawing tools. */ public void reDraw() { if (isValid()) { image = new BufferedImageTextureDrawingTools(textureDrawer.getTextureSize()); image.accept(textureDrawer); } } /** * Texture drawer setter. * @param textureDrawer the new texture drawer. */ public void setTextureDrawingTools(TextureDrawer textureDrawer) { this.textureDrawer = textureDrawer; reDraw(); } @Override public Dimension getTextureSize() { if (isValid()) { return textureDrawer.getTextureSize(); } else { return new Dimension(-1, -1); } } @Override public ByteBuffer getData() { if (isValid()) { if (image == null) { reDraw(); } return image.getImage().getRGBABuffer(); } else { return null; } } @Override public ByteBuffer getSubData(int x, int y, int width, int height) { if (isValid()) { ByteBuffer buffer = getData(); return buffer; /* ByteBuffer tempBuffer = ByteBuffer.allocate(4 * width * height); byte[] data = new byte[4 * height]; for (int j = y; j < y + height; j++) { buffer.position(4 * (x + j * getTextureSize().width)); buffer.get(data); tempBuffer.put(data); } tempBuffer.rewind(); buffer.rewind(); return tempBuffer; */ } else { return null; } } @Override public BufferedImage getImage() { if (isValid()) { if (image == null) { reDraw(); } return image.getImage(); } else { return null; } } @Override public BufferedImage getSubImage(int x, int y, int width, int height) { if (isValid()) { BufferedImage image = getImage(); return image.getSubimage(x, y, width, height); } else { return null; } } @Override public boolean isValid() { return textureDrawer != null; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/TextEntity.java000066400000000000000000000113561212506735300267360ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import org.scilab.forge.scirenderer.shapes.appearance.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; /** * @author Pierre Lando */ public class TextEntity { /** * The default text color. */ public static final Color DEFAULT_TEXT_COLOR = new Color(0.f, 0.f, 0.f); /** * The default text anti-aliased status. */ public static final boolean DEFAULT_TEXT_ANTI_ALIASED = true; /** * The default text use fractional matrix status. */ public static final boolean DEFAULT_TEXT_USE_FRACTIONAL_METRICS = true; /** * The default font. */ private static final Font DEFAULT_FONT = new Font(null); /** * The current text color. */ private Color textColor = DEFAULT_TEXT_COLOR; /** * The current text anti-aliased status. */ private boolean textAntiAliased = DEFAULT_TEXT_ANTI_ALIASED; /** * The current text use fractional matrix status. */ private boolean textUseFractionalMetrics = DEFAULT_TEXT_USE_FRACTIONAL_METRICS; /** * The text content of this object. */ private String text; /** * The font used by this text entity. */ private Font font; /** * Default constructor. * @param text the text content. */ public TextEntity(String text) { this.text = text; this.font = DEFAULT_FONT; } /** * Return the text content. * @return the text content. */ public String getText() { return text; } /** * Set the text content. * @param text the new text content. */ public void setText(String text) { this.text = text; } /** * Return the text font. * @return the text font. */ public Font getFont() { return font; } /** * Set the text font. * @param font the new text font. */ public void setFont(Font font) { this.font = font; } /** * Return the text color. * @return the text color. */ public Color getTextColor() { return textColor; } /** * Set the text color. * @param textColor the new text color. */ public void setTextColor(Color textColor) { this.textColor = textColor; } /** * Return the text anti-aliased status. * @return the text anti-aliased status. */ public boolean isTextAntiAliased() { return textAntiAliased; } /** * Set the text anti-aliased status. * @param textAntiAliased the new text anti-aliased status. */ public void setTextAntiAliased(boolean textAntiAliased) { this.textAntiAliased = textAntiAliased; } /** * Return the text use fractional metrics status. * @return the text use fractional metrics status. */ public boolean isTextUseFractionalMetrics() { return textUseFractionalMetrics; } /** * Set the text use fractional metrics status. * @param textUseFractionalMetrics the new text use fractional metrics status. */ public void setTextUseFractionalMetrics(boolean textUseFractionalMetrics) { this.textUseFractionalMetrics = textUseFractionalMetrics; } /** * TextEntity validity getter. * @return true if the text entity is valid. */ public boolean isValid() { return ((getFont() != null) && (getText() != null) && (getText().length() > 0) ); } /** * Return the dimension in pixel of the text entity. * @return the dimension in pixel of the text entity. */ public Dimension getSize() { if (isValid()) { FontRenderContext frc = new FontRenderContext(null, isTextAntiAliased(), isTextUseFractionalMetrics()); TextLayout textLayout = new TextLayout(getText(), getFont(), frc); Dimension dimension = new Dimension(); Rectangle2D r = textLayout.getBounds(); /* +1 added to fix rendering of ticks labels, a pixel row/column was missing */ dimension.setSize(r.getWidth() + 2, r.getHeight() + 1); return dimension; } else { return new Dimension(0, 0); } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/Texture.java000066400000000000000000000101021212506735300262410ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import org.scilab.forge.scirenderer.data.DataUser; /** * @author Pierre Lando */ public interface Texture extends DataUser { /** * Enumeration of wrapping possibility. */ public enum Wrap { /** * REPEAT: the integer part of the texture coordinate to be ignored. */ REPEAT, /** * CLAMP: the texture coordinate is clamped to [0, 1]. */ CLAMP } /** * Enumeration of filtering possibility. */ public enum Filter { /** * Use the value of the texture element that is nearest (in Manhattan distance) to the center of the pixel being textured. */ NEAREST, /** * Use the weighted average of the four texture elements that are closest to the center of the pixel being textured. */ LINEAR } /** * Texture validity getter. * @return true is this texture is valid and can be used for rendering. */ boolean isValid(); /** * Wrapping mode on the first texture coordinate getter. * For more information on wrapping mode {see Wrap}. * @return the wrapping mode on the first texture coordinate. */ Wrap getSWrappingMode(); /** * Wrapping mode on the first texture coordinate. * @param wrappingMode the new wrapping mode on the first texture coordinate. */ void setSWrappingMode(Wrap wrappingMode); /** * Wrapping mode on the second dimension getter. * If the texture dimension is 1, this method will return null. * For more information on wrapping mode {see Wrap}. * @return the wrapping mode on the second dimension. */ Wrap getTWrappingMode(); /** * Wrapping mode on the second texture coordinate. * @param wrappingMode the new wrapping mode on the second texture coordinate. */ void setTWrappingMode(Wrap wrappingMode); /** * Minifying filter getter. * @return the used minifying filter. */ Filter getMinifyingFilter(); /** * Minifying filter mode setter. * @param minifyingFilter the new minifying filter mode. */ void setMinifyingFilter(Filter minifyingFilter); /** * Magnification filter getter. * @return the used magnification filter. */ Filter getMagnificationFilter(); /** * Magnification filter mode setter. * @param magnificationFilter the new minifying filter mode. */ void setMagnificationFilter(Filter magnificationFilter); /** * Texture data provider getter. * @return the texture data provider. */ TextureDataProvider getDataProvider(); /** * Texture data provider setter. * The texture is set to 'no up to date'. * @param provider the new texture data provider. */ void setDataProvider(TextureDataProvider provider); /** * Set the texture data provider as a drawn texture data provider. * @param textureDrawer the given texture drawer. */ void setDrawer(TextureDrawer textureDrawer); /** * 2D-Texture coordinates must be modified according to the real texture dimension which can differ from * the textureSize (with certains GC, a texture must have a size which is a power-of-two). * @return the scale factor for the s-coordinate */ double getSScaleFactor(); /** * 2D-Texture coordinates must be modified according to the real texture dimension which can differ from * the textureSize (with certains GC, a texture must have a size which is a power-of-two). * @return the scale factor for the t-coordinate */ double getTScaleFactor(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/TextureBufferedImage.java000066400000000000000000000051571212506735300306650ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import java.awt.BorderLayout; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.nio.ByteBuffer; /** * @author Pierre Lando */ public class TextureBufferedImage extends BufferedImage { private static final int A_SHIFT = 24; private static final int R_SHIFT = 16; private static final int G_SHIFT = 8; private static final int B_SHIFT = 0; private static final int COMPONENT_MASK = 0xFF; private static final int NB_COMPONENTS = 4; /** * Default constructor. * @param width texture width. * @param height texture height. */ public TextureBufferedImage(int width, int height) { super(width, height, TYPE_INT_ARGB); } /** * Return the buffer data of the image. * Returned data are stored in 4 bytes (RGBA) per pixel. * @return the buffer data of the image. */ public byte[] getRGBAData() { int[] pixels = ((DataBufferInt) getRaster().getDataBuffer()).getData(); byte[] bytes = new byte[pixels.length * NB_COMPONENTS]; int j = 0; for (int p : pixels) { bytes[j] = (byte) ((p >> R_SHIFT) & COMPONENT_MASK); bytes[j + 1] = (byte) ((p >> G_SHIFT) & COMPONENT_MASK); bytes[j + 2] = (byte) ((p >> B_SHIFT) & COMPONENT_MASK); bytes[j + 3] = (byte) ((p >> A_SHIFT) & COMPONENT_MASK); j += NB_COMPONENTS; } //updateFrame(this); return bytes; } static JLabel label; private static void updateFrame(TextureBufferedImage textureBufferedImage) { if (label == null) { JFrame frame = new JFrame("Test"); frame.setLayout(new BorderLayout()); label = new JLabel(); frame.add(label, BorderLayout.CENTER); frame.setSize(500, 500); frame.setVisible(true); } label.setIcon(new ImageIcon(textureBufferedImage)); } /** * Buffered data getter. * @return a byte buffer filled with RGBA data. */ public ByteBuffer getRGBABuffer() { return ByteBuffer.wrap(getRGBAData()); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/TextureDataProvider.java000066400000000000000000000031231212506735300305530ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import org.scilab.forge.scirenderer.data.DataProvider; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; /** * @author Pierre Lando */ public interface TextureDataProvider extends DataProvider { /** * Texture size getter. * @return the size of the texture in pixel. */ Dimension getTextureSize(); /** * Data getter. * @return the data. */ ByteBuffer getData(); /** * Sub-data getter. * @param x rectangle origin x-coordinate. * @param y rectangle origin y-coordinate. * @param width rectangle width. * @param height rectangle height. * @return the data. */ ByteBuffer getSubData(int x, int y, int width, int height); /** * @return the data as a BufferedImage */ BufferedImage getImage(); /** * @param x rectangle origin x-coordinate. * @param y rectangle origin y-coordinate. * @param width rectangle width. * @param height rectangle height. * @return the sub-data as a BufferedImage. */ BufferedImage getSubImage(int x, int y, int width, int height); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/TextureDrawer.java000066400000000000000000000024051212506735300274150ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import java.awt.Dimension; /** * @author Pierre Lando */ public interface TextureDrawer { /** * Origin position. */ public enum OriginPosition { /** * Origin is the sprite center. */ CENTER, /** * Origin is the upper left sprite corner. */ UPPER_LEFT } /** * Call the texture drawing. * @param textureDrawingTools the used drawing tools. */ void draw(TextureDrawingTools textureDrawingTools); /** * Texture size getter. * @return texture size. */ Dimension getTextureSize(); /** * Return the origin position. * Warning: change the returned value during a draw call have no effect. * @return the origin position. */ OriginPosition getOriginPosition(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/TextureDrawingTools.java000066400000000000000000000051601212506735300306060ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import org.scilab.forge.scirenderer.shapes.appearance.Appearance; import org.scilab.forge.scirenderer.shapes.appearance.Color; import javax.swing.Icon; /** * * Interface for the sprite drawing tools. * * * @author Pierre Lando */ public interface TextureDrawingTools { /** * Draw a plus. * @param size the plus size. * @param appearance the used appearance. */ void drawPlus(int size, Appearance appearance); /** * Draw a polyline. * @param coordinates polyline's point coordinates. * @param appearance the used appearance. */ void drawPolyline(int[] coordinates, Appearance appearance); /** * Fill a polygon. * @param coordinates polygon's point coordinates. * @param appearance the used appearance. */ void fillPolygon(int[] coordinates, Appearance appearance); /** * Draw a circle. * @param x the x coordinate of the circle center. * @param y the y coordinate of the circle center. * @param diameter the circle diameter. * @param appearance the circle appearance. */ void drawCircle(int x, int y, int diameter, Appearance appearance); /** * Fill a disc of given diameter, centered at (x, y) with the given appearance. * @param x the x coordinate of the disc center. * @param y the y coordinate of the disc center. * @param diameter the disc diameter. * @param color the disc color. */ void fillDisc(int x, int y, int diameter, Color color); /** * Draw the given text at the given position with the given appearance. * @param textEntity the text entity to draw. * @param x the x text position. * @param y the y text position. */ void draw(TextEntity textEntity, int x, int y); /** * Draw the given {@link javax.swing.Icon} at the given position. * @param icon the given icon to paint. * @param x the x text position. * @param y the y text position. */ void draw(Icon icon, int x, int y); /** * Clear the sprite with the given color. * @param color the new background color. */ void clear(Color color); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/texture/TextureManager.java000066400000000000000000000015141212506735300275430ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2012 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.texture; import java.util.Collection; /** * @author Pierre Lando */ public interface TextureManager { /** * Texture creator. * @return a new {@link Texture} */ Texture createTexture(); /** * Dispose the given textures. * @param textures textures to dispose. */ void dispose(Collection textures); void dispose(Texture texture); }scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/000077500000000000000000000000001212506735300253125ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/DegenerateMatrixException.java000066400000000000000000000015421212506735300332660ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; import org.scilab.forge.scirenderer.SciRendererException; /** * @author Pierre Lando */ @SuppressWarnings(value = { "serial" }) public class DegenerateMatrixException extends SciRendererException { /** * Default constructor. * @param message the message associated with this exception. */ public DegenerateMatrixException(String message) { super(message); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/Rotation.java000066400000000000000000000213451212506735300277610ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; /** * This class represent a Rotation. * The data are stored as an unitary quaternion [a; b; c; d]. * A rotation of an angle alpha along the vector [x; y; z] is stored thus : * a = cos (alpha / 2) * b = sin (alpha / 2) * nx * c = sin (alpha / 2) * ny * d = sin (alpha / 2) * nz * * Where [nx; ny; nz] is [x; y; z] / norm([x; y; z]). * * @author Pierre Lando */ public class Rotation { private static final int MAX_SELF_OPERATION = 16; private int opCount; private double a; private double b; private double c; private double d; private double[] rotationMatrix; /** * Default constructor. * The created object represent identity rotation. */ public Rotation() { a = 1; b = 0; c = 0; d = 0; normalize(); } /** * Copy constructor. * The created object is a copy of the given rotation r. * @param r the given rotation. */ public Rotation(Rotation r) { a = r.a; b = r.b; c = r.c; d = r.d; normalize(); } /** * The created object represent a rotation of an angle of 'alpha' radians along the vector 'v'. * @param alpha the rotation angle in radians. * @param v the vector carrying the rotation. */ public Rotation(double alpha, Vector3d v) { double t = Math.cos(alpha / 2); Vector3d nv = v.getNormalized().times(Math.sin(alpha / 2)); a = t; b = nv.getX(); c = nv.getY(); d = nv.getZ(); normalize(); } /** * The created object represent a rotation of an angle of 'alpha' radians along the vector 'v'. * @param alpha the rotation angle in radians. * @param v the vector carrying the rotation. */ public Rotation(double alpha, Vector3f v) { this(alpha, v.asDouble()); } /** * Get a rotation from an angle alpha given in degree and an axis v * @param alpha angle of rotation in degree * @param v the axis of the rotation * @return a Rotation object * * For information, the function has been written to fix bug 11399. * For angle (in radians) close to Pi the Rotation has a 'a' close to 0 * and that conflicts with small axes where length is closed to a: rounding errors * led to a "bad" transformation matrix (AxesDrawer::computeBoxTransformation). */ public static Rotation getDegreeRotation(double alpha, Vector3d v) { int a = (int) alpha; if (alpha == a) { a = a % 360; if (a == 0) { return new Rotation(1, 0, 0, 0); } if (a == 180) { Vector3d nv = v.getNormalized(); return new Rotation(0, nv.getX(), nv.getY(), nv.getZ()); } return new Rotation(((double) a) / 180.0 * Math.PI, v); } alpha = (alpha / 180.0 - 2 * Math.floor(alpha / 360.0)) * Math.PI; return new Rotation(alpha, v); } private Rotation(double a, double b, double c, double d) { this.a = a; this.b = b; this.c = c; this.d = d; normalize(); } public Rotation(float[] v) { if ((v != null) && (v.length == 4)) { a = v[0]; b = v[1]; c = v[2]; d = v[3]; } else { // TODO throw invalid data exception a = 1; b = 0; c = 0; d = 0; } normalize(); } public Rotation(double[] v) { if ((v != null) && (v.length == 4)) { a = v[0]; b = v[1]; c = v[2]; d = v[3]; } else { // TODO throw invalid data exception a = 1; b = 0; c = 0; d = 0; } normalize(); } /** * Return the inverse rotation. * @return the inverse rotation. */ public Rotation getInverse() { return new Rotation(a, -b, -c, -d); } /** * Return true if this object represents an identity transformation. * @return true if this object represents an identity transformation. */ public boolean isIdentity() { return (a == 1); } public double[] getRotationMatrix() { return rotationMatrix.clone(); } public double[] getUnRotateMatrix() { return new double[] { rotationMatrix[0], rotationMatrix[4], rotationMatrix[8], rotationMatrix[12], rotationMatrix[1], rotationMatrix[5], rotationMatrix[9], rotationMatrix[13], rotationMatrix[2], rotationMatrix[6], rotationMatrix[10], rotationMatrix[14], rotationMatrix[3], rotationMatrix[7], rotationMatrix[11], rotationMatrix[15] }; } public Rotation multiply(Rotation q) { double ar = a * q.a - b * q.b - c * q.c - d * q.d; double br = a * q.b + b * q.a + c * q.d - d * q.c; double cr = a * q.c - b * q.d + c * q.a + d * q.b; double dr = a * q.d + b * q.c - c * q.b + d * q.a; a = ar; b = br; c = cr; d = dr; selfCheck(); return this; } private void selfCheck() { if (opCount++ > MAX_SELF_OPERATION) { normalize(); } else { computeRotationMatrix(); } } private void normalize() { opCount = 0; double f = 1f / Math.sqrt((a * a) + (b * b) + (c * c) + (d * d)); a *= f; b *= f; c *= f; d *= f; computeRotationMatrix(); } public Rotation times(Rotation q) { return new Rotation(this).multiply(q); } public Vector3d conjugate(Vector3d v) { return new Vector3d( rotationMatrix[0] * v.getX() + rotationMatrix[4] * v.getY() + rotationMatrix[8] * v.getZ(), rotationMatrix[1] * v.getX() + rotationMatrix[5] * v.getY() + rotationMatrix[9] * v.getZ(), rotationMatrix[2] * v.getX() + rotationMatrix[6] * v.getY() + rotationMatrix[10] * v.getZ() ); } public Vector3d conjugateInverse(Vector3d v) { return new Vector3d( rotationMatrix[0] * v.getX() + rotationMatrix[1] * v.getY() + rotationMatrix[2] * v.getZ(), rotationMatrix[4] * v.getX() + rotationMatrix[5] * v.getY() + rotationMatrix[6] * v.getZ(), rotationMatrix[8] * v.getX() + rotationMatrix[9] * v.getY() + rotationMatrix[10] * v.getZ() ); } private void computeRotationMatrix() { double a2 = a * a; double b2 = b * b; double c2 = c * c; double d2 = d * d; this.rotationMatrix = new double[] { a2 + b2 - c2 - d2, 2 * ((b * c) - (a * d)), 2 * ((a * c) + (b * d)), 0, 2 * ((a * d) + (b * c)), a2 - b2 + c2 - d2, 2 * ((c * d) - (a * b)), 0, 2 * ((b * d) - (a * c)), 2 * ((a * b) + (c * d)), a2 - b2 - c2 + d2, 0, 0, 0, 0, 1 }; } public String toString() { return "(" + a + ", " + b + ", " + c + ", " + d + ")"; } public Vector3d getVectorY() { return new Vector3d(rotationMatrix[1], rotationMatrix[5], rotationMatrix[9]); } public Rotation power(double p) { // TODO : do a better S.L.E.R.P. double cos = a; double sin = Math.sqrt((b * b) + (c * c) + (d * d)); if (sin < 0.001) { return new Rotation(); } double t = (p - 1) * Math.atan2(sin, cos); double na = cos * Math.cos(t) - sin * Math.sin(t); double beta = Math.cos(t) + Math.sin(t) * (cos / sin); return new Rotation(na, beta * b, beta * c, beta * d); } public double[] getData() { return new double[] {a, b, c, d}; } public float[] getDataAsFloatArray() { return new float[] {(float) a, (float) b, (float) c, (float) d}; } @Override public int hashCode() { int hashCode = 0; hashCode += 7 * (new Double(a).hashCode()); hashCode += 17 * (new Double(b).hashCode()); hashCode += 29 * (new Double(c).hashCode()); hashCode += 37 * (new Double(d).hashCode()); return hashCode; } public boolean equals(Rotation r2) { return (r2 != null) && (a == r2.a) && (b == r2.b) && (c == r2.c) && (d == r2.d); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/Transformation.java000066400000000000000000000044431212506735300311700ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; /** * @author Pierre Lando */ public interface Transformation { /** * Return this right times the given transformation. * @param transformation the given transformation. * @return a new transformation. */ Transformation rightTimes(Transformation transformation); /** * Return this left times the given transformation. * @param transformation the given transformation. * @return a new transformation. */ Transformation leftTimes(Transformation transformation); /** * Return the inverse transformation. * @return the inverse transformation. */ Transformation getInverseTransformation(); /** * Project the given vector. * W value is set to 1. * @param vector the given vector. * @return the given vector projected. */ Vector3d project(Vector3d vector); /** * Project the given direction. * Translation part is not used. * @param direction the direction to project. * @return the given direction projected. */ Vector3d projectDirection(Vector3d direction); /** * Unproject the given vector. * W value is set to 1. * @param vector the given vector. * @return the given vector un-projected. */ Vector3d unproject(Vector3d vector); /** * Return true if is identity, false otherwise. * @return true if is identity, false otherwise. */ boolean isIdentity(); /** * Return this transformation matrix. * The returned array is a clone of the transformation array. * @return this transformation matrix. */ double[] getMatrix(); /** * Return this transformation inverse matrix. * The returned array is a clone of the transformation array. * @return this transformation inverse matrix. */ double[] getInverseMatrix(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/TransformationFactory.java000066400000000000000000000521221212506735300325150ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; import java.awt.Dimension; /** * @author Pierre Lando */ public final class TransformationFactory { /** * The identity transformation. */ static final Transformation IDENTITY_TRANSFORMATION = new IdentityTransformation(); /** * Default constructor. * The constructor is private : this is an utility class. */ private TransformationFactory() { } /** * Return the identity transformation. * @return the identity transformation. */ public static Transformation getIdentity() { return IDENTITY_TRANSFORMATION; } /** * Return a translate transformation. * @param x translation in x coordinate. * @param y translation in y coordinate. * @param z translation in z coordinate. * @return a translate transformation. */ public static Transformation getTranslateTransformation(double x, double y, double z) { if ((x == 0) && (y == 0) && (z == 0)) { return IDENTITY_TRANSFORMATION; } else { return new TranslateTransformation(x, y, z); } } private static Transformation getTranslateTransformation(Vector3d t) { return getTranslateTransformation(t.getX(), t.getY(), t.getZ()); } /** * Return a scale transformation. * @param x scale in x. * @param y scale in y. * @param z scale in z. * @return a scale transformation. * @throws DegenerateMatrixException - A DegenerateMatrixException is thrown if one of the scale factor is zero. */ public static Transformation getScaleTransformation(double x, double y, double z) throws DegenerateMatrixException { if ((x == 1) && (y == 1) && (z == 1)) { return IDENTITY_TRANSFORMATION; } else if ((x == 0) || (y == 0) || (z == 0)) { throw new DegenerateMatrixException("Scale matrix with 0 factor."); } else { return new ScaleTransformation(x, y, z); } } /** * Return a scale transformation. * @param s scale vector. * @return a scale transformation. * @throws DegenerateMatrixException - A DegenerateMatrixException is thrown if one coordinate of the scale vector is zero. */ private static Transformation getScaleTransformation(Vector3d s) throws DegenerateMatrixException { return getScaleTransformation(s.getX(), s.getY(), s.getZ()); } /** * Return a scale transformation. * @param s scale value. * @return a scale transformation. * @throws DegenerateMatrixException - A DegenerateMatrixException is thrown if one coordinate of the scale vector is zero. */ public static Transformation getScaleTransformation(double s) throws DegenerateMatrixException { return getScaleTransformation(s, s, s); } /** * Return a rotation transformation. * @param angle the rotation angle in degree. * @param x the x coordinate of the rotation axes. * @param y the y coordinate of the rotation axes. * @param z the z coordinate of the rotation axes. * @return a rotation transformation. * @throws DegenerateMatrixException - A DegenerateMatrixException is thrown if the rotation axes is zero. */ public static Transformation getRotationTransformation(double angle, double x, double y, double z) throws DegenerateMatrixException { if ((x == 0) && (y == 0) && (z == 0)) { throw new DegenerateMatrixException("Rotation axes should not be nul."); } else if (angle == 0) { return IDENTITY_TRANSFORMATION; } else { return new RotationTransformation(Rotation.getDegreeRotation(angle, new Vector3d(x, y, z))); } } /** * Return a rotation transformation. * @param q the quaternion. * @return a rotation transformation. */ public static Transformation getRotationTransformation(Rotation q) { if (q.isIdentity()) { return IDENTITY_TRANSFORMATION; } else { return new RotationTransformation(q); } } /** * Return the 'preferred aspect ratio transformation' * @param dimension the canvas dimension. * @param preferredRatio the preferred aspect ratio. * @return the 'preferred aspect ratio transformation' * @throws DegenerateMatrixException - A DegenerateMatrixException is thrown if the given value are not reasonable. */ public static Transformation getPreferredAspectRatioTransformation(Dimension dimension, double preferredRatio) throws DegenerateMatrixException { double ratio = dimension.getWidth() / dimension.getHeight(); if (ratio > preferredRatio) { return getScaleTransformation(1 / ratio, 1, 1); } else { return getScaleTransformation(1, ratio, 1); } } /** * Return a perspective transformation. * @param near the distance from the viewer to the near clipping plane. * @param far the distance from the viewer to the far clipping plane. * @param fov the field of view angle in degree. * @return a perspective transformation. */ public static Transformation getPerspectiveTransformation(double near, double far, double fov) { return new PerspectiveTransformation(near, far, fov); } /** * Return an orthographic transformation. * @param left the left plane distance to origin. * @param right the right plane distance to origin. * @param bottom the bottom plane distance to origin. * @param top the top plane distance to origin. * @param near the near plane distance to origin. * @param far the far plane distance to origin. * @return an orthographic transformation. */ public static Transformation getOrthographic(double left, double right, double bottom, double top, double near, double far) { return new OrthographicTransformation(left, right, bottom, top, near, far); } /** * Return an affine transformation * aX + b * @param s the scale parameter. * @param t the translate parameter. * @return an affine transformation * @throws DegenerateMatrixException - A DegenerateMatrixException is thrown if one coordinate of the scale vector is zero. */ public static Transformation getAffineTransformation(Vector3d s, Vector3d t) throws DegenerateMatrixException { return getTranslateTransformation(t).rightTimes(getScaleTransformation(s)); } /** * Abstract transformation. * Implement common methods of all transformation. */ private abstract static class AbstractTransformation implements Transformation { @Override public Transformation rightTimes(Transformation transformation) { return getProductTransformation(this, transformation); } @Override public Transformation leftTimes(Transformation transformation) { return getProductTransformation(transformation, this); } @Override public Vector3d project(Vector3d vector) { double[] matrix = getMatrix(); double x = matrix[0] * vector.getX() + matrix[4] * vector.getY() + matrix[8] * vector.getZ() + matrix[12]; double y = matrix[1] * vector.getX() + matrix[5] * vector.getY() + matrix[9] * vector.getZ() + matrix[13]; double z = matrix[2] * vector.getX() + matrix[6] * vector.getY() + matrix[10] * vector.getZ() + matrix[14]; double w = matrix[3] * vector.getX() + matrix[7] * vector.getY() + matrix[11] * vector.getZ() + matrix[15]; return new Vector3d(x / w, y / w, z / w); } @Override public Vector3d projectDirection(Vector3d direction) { double[] matrix = getMatrix(); double x = matrix[0] * direction.getX() + matrix[4] * direction.getY() + matrix[8] * direction.getZ(); double y = matrix[1] * direction.getX() + matrix[5] * direction.getY() + matrix[9] * direction.getZ(); double z = matrix[2] * direction.getX() + matrix[6] * direction.getY() + matrix[10] * direction.getZ(); double w = matrix[3] * direction.getX() + matrix[7] * direction.getY() + matrix[11] * direction.getZ() + matrix[15]; return new Vector3d(x / w, y / w, z / w); } @Override public Vector3d unproject(Vector3d vector) { return getInverseTransformation().project(vector); } @Override public Transformation getInverseTransformation() { return new AbstractTransformation() { @Override public boolean isIdentity() { return AbstractTransformation.this.isIdentity(); } @Override public double[] getMatrix() { return AbstractTransformation.this.getInverseMatrix(); } @Override public double[] getInverseMatrix() { return AbstractTransformation.this.getMatrix(); } }; } @Override public String toString() { double[] matrix = getMatrix(); String r = ""; for (int i = 0; i < 16; i++) { r += matrix[i]; if ((i % 4) == 3) { r += "\n"; } else { r += ", "; } } return r; } /** * Return a product transformation. * @param t1 the first transformation. * @param t2 the second transformation. * @return t1 x t2 */ private Transformation getProductTransformation(Transformation t1, Transformation t2) { if (t1.isIdentity()) { return t2; } else if (t2.isIdentity()) { return t1; } else { return new ProductTransformation(t1, t2); } } } /** * The identity transformation. */ private static class IdentityTransformation extends AbstractTransformation { /** * The identity matrix data. */ private static final double[] IDENTITY_MATRIX = new double[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; /** * Default constructor. */ IdentityTransformation() { } @Override public Transformation rightTimes(Transformation transformation) { return transformation; } @Override public Transformation leftTimes(Transformation transformation) { return transformation; } @Override public Vector3d project(Vector3d vector) { return vector; } @Override public Vector3d projectDirection(Vector3d direction) { return direction; } @Override public Vector3d unproject(Vector3d vector) { return vector; } @Override public boolean isIdentity() { return true; } @Override public double[] getMatrix() { return IDENTITY_MATRIX.clone(); } @Override public double[] getInverseMatrix() { return IDENTITY_MATRIX.clone(); } } /** * A translate transformation. */ private static class TranslateTransformation extends AbstractTransformation { /** * translation in x coordinate. */ private final double x; /** * translation in y coordinate. */ private final double y; /** * translation in z coordinate. */ private final double z; /** * Default constructor. * * (x, y, z) != (0, 0, 0). * * @param x translation in x coordinate. * @param y translation in y coordinate. * @param z translation in z coordinate. */ public TranslateTransformation(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } @Override public Vector3d project(Vector3d vector) { return new Vector3d(vector.getX() + x, vector.getY() + y, vector.getZ() + z); } @Override public Vector3d unproject(Vector3d vector) { return new Vector3d(vector.getX() - x, vector.getY() - y, vector.getZ() - z); } @Override public boolean isIdentity() { return false; } @Override public double[] getMatrix() { return new double[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 }; } @Override public double[] getInverseMatrix() { return new double[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -x, -y, -z, 1 }; } } /** * A scale transformation. */ private static class ScaleTransformation extends AbstractTransformation { /** * scale in x coordinate. */ private final double x; /** * scale in y coordinate. */ private final double y; /** * scale in z coordinate. */ private final double z; /** * Default constructor. * * x, y and z not 0 or 1. * * @param x scale in x coordinate. * @param y scale in y coordinate. * @param z scale in z coordinate. */ public ScaleTransformation(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } @Override public Vector3d project(Vector3d vector) { return new Vector3d(vector.getX() * x, vector.getY() * y, vector.getZ() * z); } @Override public Vector3d unproject(Vector3d vector) { return new Vector3d(vector.getX() / x, vector.getY() / y, vector.getZ() / z); } @Override public boolean isIdentity() { return false; } @Override public double[] getMatrix() { return new double[] { x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 }; } @Override public double[] getInverseMatrix() { return new double[] { 1 / x, 0, 0, 0, 0, 1 / y, 0, 0, 0, 0, 1 / z, 0, 0, 0, 0, 1 }; } } /** * A perspective transformation. */ private static class PerspectiveTransformation extends AbstractTransformation { private final double[] matrix; private final double[] inverseMatrix; /** * Default constructor. * @param near the distance to the near plane. * @param far the distance to the far plane. * @param fov the field of view in degree. */ PerspectiveTransformation(double near, double far, double fov) { double fInv = Math.tan(Math.toRadians(fov / 2)); double f = 1 / fInv; matrix = new double[] { f, 0, 0, 0, 0, f, 0, 0, 0, 0, (far + near) / (near - far), -1, 0, 0, 2 * far * near / (near - far), 0 }; inverseMatrix = new double[] { fInv, 0, 0, 0, 0, fInv, 0, 0, 0, 0, 0, (near - far) / (2 * far * near), 0, 0, -1, (near + far) / (2 * far * near) }; } @Override public boolean isIdentity() { return false; } @Override public double[] getMatrix() { return matrix.clone(); } @Override public double[] getInverseMatrix() { return inverseMatrix.clone(); } } /** * An orthographic transformation. */ private static class OrthographicTransformation extends AbstractTransformation { private final double[] matrix; private final double[] inverseMatrix; private final boolean isIdentity; /** * Default constructor. * @param left the left plane distance to origin. * @param right the right plane distance to origin. * @param bottom the bottom plane distance to origin. * @param top the top plane distance to origin. * @param near the near plane distance to origin. * @param far the far plane distance to origin. */ public OrthographicTransformation(double left, double right, double bottom, double top, double near, double far) { double tx = (right + left) / (left - right); double ty = (top + bottom) / (bottom - top); double tz = (far + near) / (near - far); matrix = new double[] { 2 / (right - left), 0, 0, 0, 0, 2 / (top - bottom), 0, 0, 0, 0, 2 / (near - far), 0, tx, ty, tz, 1 }; inverseMatrix = new double[] { (right - left) / 2, 0, 0, 0, 0, (top - bottom) / 2, 0, 0, 0, 0, (near - far) / 2, 0, (right + left) / 2, (top + bottom) / 2, -(near + far) / 2, 1 }; isIdentity = ((left == -1) && (right == 1) && (bottom == -1) && (top == 1) && (far == -1) && (near == 1)); } @Override public boolean isIdentity() { return isIdentity; } @Override public double[] getMatrix() { return matrix.clone(); } @Override public double[] getInverseMatrix() { return inverseMatrix.clone(); } } /** * A rotation transformation. */ private static class RotationTransformation extends AbstractTransformation { private final double[] matrix; private final double[] inverseMatrix; /** * Default constructor. * @param q the quaternion. */ public RotationTransformation(Rotation q) { matrix = q.getRotationMatrix(); inverseMatrix = q.getUnRotateMatrix(); } @Override public boolean isIdentity() { return false; } @Override public double[] getMatrix() { return matrix.clone(); } @Override public double[] getInverseMatrix() { return inverseMatrix.clone(); } } /** * A product transformation. */ private static class ProductTransformation extends AbstractTransformation { private final double[] matrix; private final double[] inverseMatrix; private final boolean isIdentity; /** * Default constructor. * @param t1 first transformation. * @param t2 first transformation. */ public ProductTransformation(Transformation t1, Transformation t2) { isIdentity = t1.isIdentity() && t2.isIdentity(); matrix = multiply(t1.getMatrix(), t2.getMatrix()); // TODO : inverse 'matrix' instead. inverseMatrix = multiply(t2.getInverseMatrix(), t1.getInverseMatrix()); } @Override public boolean isIdentity() { return isIdentity; } @Override public double[] getMatrix() { return matrix.clone(); } @Override public double[] getInverseMatrix() { return inverseMatrix.clone(); } } /** * Multiply two matrix. * @param matrix1 first matrix. * @param matrix2 second matrix. * @return matrix1 x matrix2 */ private static double[] multiply(double[] matrix1, double[] matrix2) { double[] result = new double[16]; for (int l = 0; l < 4; l++) { for (int c = 0; c < 4; c++) { double r = 0; for (int i = 0; i < 4; i++) { r += matrix1[(4 * i) + c] * matrix2[(4 * l) + i]; } result[(4 * l) + c] = r; } } return result; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/TransformationManager.java000066400000000000000000000057501212506735300324650ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; /** * * This is an interface for a transformation manager. * The transformation manager is used to manage transformation applied to vertex data sent for drawing. * * Coordinate are in first multiplied by the matrix at the top of ModelView matrix stack. * And then, the result is multiplied by the matrix at the top of Projection matrix stack. * * 'Projection' and 'ModelView' name refers to OpenGl 1.1. * * The rendered vertex are in the box [-1, 1]^3. * * @author Pierre Lando */ public interface TransformationManager { /** * Add a listener. * @param listener added. */ void addListener(TransformationManagerListener listener); /** * Remove a listener. * @param listener removed. */ void removeListener(TransformationManagerListener listener); /** * Return the model view matrix stack. * @return the model view matrix stack. */ TransformationStack getModelViewStack(); /** * Return the projection matrix stack. * @return the projection matrix stack. */ TransformationStack getProjectionStack(); /** * Return the top scene transformation. * @return the top scene transformation. */ Transformation getTransformation(); /** * Return the inverse of window transformation. * @return the inverse window transformation. */ Transformation getInverseWindowTransformation(); /** * Return the window transformation. * @return the window transformation. */ Transformation getWindowTransformation(); /** * Return the canvas projection matrix. * @return the canvas projection matrix. */ Transformation getCanvasProjection(); /** * Return the canvas projection matrix for Graphics2D. * @return the canvas projection matrix. */ Transformation getG2DProjection(); /** * Return the projection matrix (no modelView). * @return the projection matrix. */ Transformation getG2DSingleProjection(); /** * Return the window projection matrix for Graphics2D. * @return the window projection matrix. */ Transformation getG2DWindowProjection(); /** * Clear all stack. */ void reset(); /** * Switch to window coordinate. */ void useWindowCoordinate(); /** * Switch to scene coordinate. */ void useSceneCoordinate(); /** * Return true if is using scene coordinate. * @return true if is using scene coordinate. */ boolean isUsingSceneCoordinate(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/TransformationManagerImpl.java000066400000000000000000000164211212506735300333040ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; import org.scilab.forge.scirenderer.Canvas; import javax.swing.event.EventListenerList; /** * Default {@link org.scilab.forge.scirenderer.tranformations.TransformationManager} implementation. * @author Pierre Lando */ public class TransformationManagerImpl implements TransformationManager { /** * We use swing EventListenerList for facility. */ private final EventListenerList listeners; private final Canvas canvas; private final TransformationStack modelViewStack; private final TransformationStack projectionStack; /** * The peek transformation value. * Set to null if it must be recalculate. */ private Transformation topTransformation; private boolean usingSceneCoordinate = true; /** * Standard constructor. * @param canvas the canvas. */ public TransformationManagerImpl(Canvas canvas) { this.canvas = canvas; listeners = new EventListenerList(); modelViewStack = new TransformationStackImpl(); projectionStack = new TransformationStackImpl(); topTransformation = null; final TransformationStackListener listener = new TransformationStackListener() { @Override public void changed(TransformationStack transformationStack, TransformationStack.TransformationStackEvent event, Transformation top) { topTransformation = null; fireTransformationChanged(); } }; modelViewStack.addListener(listener); projectionStack.addListener(listener); } @Override public void addListener(TransformationManagerListener listener) { listeners.add(TransformationManagerListener.class, listener); } @Override public void removeListener(TransformationManagerListener listener) { listeners.remove(TransformationManagerListener.class, listener); } @Override public TransformationStack getModelViewStack() { return modelViewStack; } @Override public TransformationStack getProjectionStack() { return projectionStack; } @Override public Transformation getTransformation() { if (topTransformation == null) { final Transformation modelView = modelViewStack.peek(); final Transformation projection = projectionStack.peek(); final Transformation returnedTransformation = projection.rightTimes(modelView); topTransformation = returnedTransformation; return returnedTransformation; } else { return topTransformation; } } @Override public Transformation getWindowTransformation() { double w = 2.0 / canvas.getWidth(); double h = 2.0 / canvas.getHeight(); try { return TransformationFactory.getAffineTransformation( new Vector3d(w, h, 1), new Vector3d(-1, -1, 0) ); } catch (DegenerateMatrixException e) { // Should not occur as long as canvas have not infinite size. throw new Error("Canvas is to big.", e); } } @Override public Transformation getInverseWindowTransformation() { double w = canvas.getWidth() / 2; double h = canvas.getHeight() / 2; try { return TransformationFactory.getAffineTransformation( new Vector3d(w, h, 1), new Vector3d(w, h, 0) ); } catch (DegenerateMatrixException e) { // Should not occur as long as canvas have not infinite size. throw new Error("Canvas is to big.", e); } } @Override public Transformation getCanvasProjection() { double w = canvas.getWidth() / 2.0; double h = canvas.getHeight() / 2.0; try { Transformation windowTransformation = TransformationFactory.getAffineTransformation( new Vector3d(w, h, 1), new Vector3d(w, h, 0) ); return windowTransformation.rightTimes(getTransformation()); } catch (DegenerateMatrixException e) { // Should not occur as long as canvas have not infinite size. throw new Error("Canvas is to big.", e); } } @Override public Transformation getG2DProjection() { double w = canvas.getWidth() / 2.0; double h = canvas.getHeight() / 2.0; try { Transformation windowTransformation = TransformationFactory.getAffineTransformation( new Vector3d(w, -h, 1), new Vector3d(w, h, 0) ); return windowTransformation.rightTimes(getTransformation()); } catch (DegenerateMatrixException e) { // Should not occur as long as canvas have not infinite size. throw new Error("Canvas is to big.", e); } } @Override public Transformation getG2DSingleProjection() { double w = canvas.getWidth() / 2.0; double h = canvas.getHeight() / 2.0; try { Transformation windowTransformation = TransformationFactory.getAffineTransformation( new Vector3d(w, -h, 1), new Vector3d(w, h, 0) ); return windowTransformation.rightTimes(projectionStack.peek()); } catch (DegenerateMatrixException e) { // Should not occur as long as canvas have not infinite size. throw new Error("Canvas is to big.", e); } } @Override public Transformation getG2DWindowProjection() { double h = canvas.getHeight(); try { return TransformationFactory.getAffineTransformation( new Vector3d(1, -1, 1), new Vector3d(0, h, 0) ); } catch (DegenerateMatrixException e) { // Should not occur as long as canvas have not infinite size. throw new Error("Canvas is to big.", e); } } @Override public void reset() { modelViewStack.clear(); projectionStack.clear(); } @Override public void useWindowCoordinate() { if (isUsingSceneCoordinate()) { usingSceneCoordinate = false; fireTransformationChanged(); } } @Override public void useSceneCoordinate() { if (!isUsingSceneCoordinate()) { usingSceneCoordinate = true; fireTransformationChanged(); } } @Override public boolean isUsingSceneCoordinate() { return usingSceneCoordinate; } /** * Notify listeners the top transformation have changed. */ protected void fireTransformationChanged() { for (TransformationManagerListener listener : listeners.getListeners(TransformationManagerListener.class)) { listener.transformationChanged(this); } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/TransformationManagerListener.java000066400000000000000000000021111212506735300341570ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; import java.util.EventListener; /** * * The listener of a {@link org.scilab.forge.scirenderer.tranformations.TransformationManager} functions are called when events occurs in the * listened {@link org.scilab.forge.scirenderer.tranformations.TransformationManager}. * * @author Pierre Lando */ public interface TransformationManagerListener extends EventListener { /** * Called when the top transformation of the listened TransformationManager have changed. * @param transformationManager object where event occur. */ void transformationChanged(final TransformationManager transformationManager); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/TransformationStack.java000066400000000000000000000040431212506735300321520ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; /** * @author Pierre Lando */ public interface TransformationStack { /** * Enum of possible transformation stack event. */ enum TransformationStackEvent { /** * When a matrix have been popped. */ POPPED, /** * When a matrix have been pushed. */ PUSHED, /** * When the stack have been cleared. */ CLEARED } /** * Add a listener. * @param listener added listener. */ void addListener(TransformationStackListener listener); /** * Remove a listener. * @param listener removed listener. */ void removeListener(TransformationStackListener listener); /** * Return the top transformation. * @return the top transformation. */ Transformation peek(); /** * Push the given transformation on the stack. * @param transformation the given transformation. */ void push(Transformation transformation); /** * Push the given transformation right time the peek on the stack. * @param transformation the given transformation. */ void pushRightMultiply(Transformation transformation); /** * Push the given transformation left time the peek on the stack. * @param transformation the given transformation. */ void pushLeftMultiply(Transformation transformation); /** * Pop one matrix on the stack. * @return the popped matrix. */ Transformation pop(); /** * Pop all matrix on the stack except identity. */ void clear(); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/TransformationStackImpl.java000066400000000000000000000053201212506735300327730ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; import java.util.Stack; import javax.swing.event.EventListenerList; /** * @author Pierre Lando */ public class TransformationStackImpl implements TransformationStack { /** * We use swing EventListenerList for facility. */ private final EventListenerList listeners; private final Stack stack; public TransformationStackImpl() { listeners = new EventListenerList(); stack = new Stack(); } @Override public void addListener(TransformationStackListener listener) { listeners.add(TransformationStackListener.class, listener); } @Override public void removeListener(TransformationStackListener listener) { listeners.remove(TransformationStackListener.class, listener); } @Override public Transformation peek() { if (stack.isEmpty()) { return TransformationFactory.getIdentity(); } else { return stack.peek(); } } @Override public void push(Transformation transformation) { if (transformation != null) { stack.push(transformation); fireChanged(TransformationStackEvent.PUSHED, transformation); } } @Override public void pushRightMultiply(Transformation transformation) { push(peek().rightTimes(transformation)); } @Override public void pushLeftMultiply(Transformation transformation) { push(peek().leftTimes(transformation)); } @Override public Transformation pop() { Transformation value = stack.pop(); if (value == null) { value = TransformationFactory.getIdentity(); } fireChanged(TransformationStackEvent.POPPED, value); return value; } @Override public void clear() { stack.clear(); fireChanged(TransformationStackEvent.CLEARED, peek()); } /** * Fire a change event. * @param event the event. * @param top the new top transformation. */ protected void fireChanged(TransformationStackEvent event, Transformation top) { for (TransformationStackListener listener : listeners.getListeners(TransformationStackListener.class)) { listener.changed(this, event, top); } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/TransformationStackListener.java000066400000000000000000000017661212506735300336710ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; import java.util.EventListener; /** * @author Pierre Lando */ public interface TransformationStackListener extends EventListener { /** * Called when an event occur in the listened transformation stack. * @param transformationStack the transformation stack where the event occur. * @param event the event. * @param top the new peek transformation of the stack. */ void changed(final TransformationStack transformationStack, final TransformationStack.TransformationStackEvent event, final Transformation top); } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/Vector3d.java000066400000000000000000000123421212506735300276500ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; import java.util.Arrays; /** * @author Pierre Lando */ public class Vector3d { private final double x; private final double y; private final double z; private Integer hash; public Vector3d(Vector3d v) { this.x = v.x; this.y = v.y; this.z = v.z; } public Vector3d(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } public Vector3d(float[] position) { this.x = position[0]; this.y = position[1]; this.z = position[2]; } public Vector3d(double[] position) { this.x = position[0]; this.y = position[1]; this.z = position[2]; } public Vector3d(Double[] position) { this.x = position[0]; this.y = position[1]; this.z = position[2]; } public double getX() { return x; } public double getY() { return y; } public double getZ() { return z; } @Override public String toString() { return "[" + x + ", " + y + ", " + z + "]"; } public double[] getData() { return new double[] {x, y, z}; } public float[] getDataAsFloatArray() { return new float[] {(float) x, (float) y, (float) z}; } public float[] getDataAsFloatArray(int size) { if (size == 4) { return new float[] {(float) x, (float) y, (float) z, 1}; } else { return new float[] {(float) x, (float) y, (float) z}; } } public Vector3d plus(Vector3d v) { return new Vector3d(x + v.x, y + v.y, z + v.z); } public Vector3d minus(Vector3d v) { return new Vector3d(x - v.x, y - v.y, z - v.z); } public Vector3d times(double d) { return new Vector3d(x * d, y * d, z * d); } public Vector3d getNormalized() { double norm = getNorm(); if (norm == 0) { return new Vector3d(0, 0, 0); } return this.times(1 / getNorm()); } public double getNorm() { return Math.sqrt(getNorm2()); } public double getNorm2() { return scalar(this); } public double scalar(Vector3d v) { return x * v.x + y * v.y + z * v.z; } /** * Create a new vector cross-product of the given vectors. * @param v1 the first given vector. * @param v2 the second given vector. * @return a new vector cross-product of the given vectors. */ public static Vector3d product(Vector3d v1, Vector3d v2) { return new Vector3d( v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x ); } public final static double det(final Vector3d v0, final Vector3d v1, final Vector3d v2) { return v0.x * (v1.y * v2.z - v1.z * v2.y) + v0.y * (v1.z * v2.x - v1.x * v2.z) + v0.z * (v1.x * v2.y - v1.y * v2.x); } public final static Vector3d getBarycenter(Vector3d v0, Vector3d v1, double w0, double w1) { return new Vector3d(v0.x * w0 + v1.x * w1, v0.y * w0 + v1.y * w1, v0.z * w0 + v1.z * w1); } /** * Create a new vector, copy of this one, with a new X value. * @param x the new X value. * @return a new vector, copy of this one, with a new X value. */ public Vector3d setX(double x) { return new Vector3d(x, y, z); } /** * Create a new vector, copy of this one, with a new Y value. * @param y the new Y value. * @return a new vector, copy of this one, with a new Y value. */ public Vector3d setY(double y) { return new Vector3d(x, y, z); } /** * Create a new vector, copy of this one, with a new Z value. * @param z the new Z value. * @return a new vector, copy of this one, with a new Z value. */ public Vector3d setZ(double z) { return new Vector3d(x, y, z); } /** * Return true if this vector is (0, 0, 0). * @return true if this vector is (0, 0, 0). */ public boolean isZero() { return (x == 0) && (y == 0) && (z == 0); } /** * Return true if this vector is (0, 0, 0). * @return true if this vector is (0, 0, 0). */ public boolean isNearZero() { final double eps = 1e-9; return Math.abs(x) <= eps && Math.abs(y) <= eps && Math.abs(z) <= eps; } @Override public boolean equals(Object obj) { if (obj instanceof Vector3d) { Vector3d v = (Vector3d) obj; final double eps = 1e-9; return Math.abs(v.x - x) <= eps && Math.abs(v.y - y) <= eps && Math.abs(v.z - z) <= eps; } return false; } @Override public int hashCode() { if (hash == null) { hash = Arrays.hashCode(new double[]{x, y, z}); } return hash; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/Vector3f.java000066400000000000000000000020411212506735300276450ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; /** * @author Pierre Lando */ public class Vector3f { private final float x; private final float y; private final float z; public Vector3f(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } public float getX() { return x; } public float getY() { return y; } public float getZ() { return z; } @Override public String toString() { return "[" + x + ", " + y + ", " + z + "]"; } public Vector3d asDouble() { return new Vector3d(x, y, z); } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/tranformations/Vector4d.java000066400000000000000000000015371212506735300276550ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.tranformations; /** * @author Pierre Lando */ public class Vector4d { private final double[] data; public Vector4d(double x, double y, double z, double w) { data = new double[] {x, y, z, w}; } public double[] getData() { return data.clone(); } public String toString() { return "[" + data[0] + ", " + data[1] + ", " + data[2] + ", " + data[3] + "]"; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/utils/000077500000000000000000000000001212506735300234045ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/utils/shapes/000077500000000000000000000000001212506735300246675ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/utils/shapes/geometry/000077500000000000000000000000001212506735300265225ustar00rootroot00000000000000scirenderer-1.1.0/src/org/scilab/forge/scirenderer/utils/shapes/geometry/CubeFactory.java000066400000000000000000000150071212506735300315760ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.utils.shapes.geometry; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.buffers.BuffersManager; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import org.scilab.forge.scirenderer.shapes.geometry.DefaultGeometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import java.nio.FloatBuffer; import java.nio.IntBuffer; /** * An utility class to create cube geometry. * @author Pierre Lando */ public final class CubeFactory { /** * The vertex size. */ private static final int VERTEX_SIZE = 4; /** * The constructor is private : this is an utility class. */ private CubeFactory() { } /** * Return a geometry representing a simple cube. * @param canvas the canvas where the buffers are created. * @return a geometry representing a simple cube. */ public static Geometry createCube(Canvas canvas) { return createCube(canvas, 1); } /** * Return a geometry representing a cube. * Each cube face are made of density^2 square. * * @param canvas the canvas where the geometry buffers are created. * @param density the square density on cube faces. * @return a geometry representing a cube. */ public static Geometry createCube(Canvas canvas, int density) { return createCube(canvas, density, false); } /** * Return a geometry representing a cube. * Each cube face are made of density^2 square. * * @param canvas the canvas where the geometry buffers are created. * @param density the square density on cube faces. * @param wired true if the wire is visible. * @return a geometry representing a cube. */ public static Geometry createCube(Canvas canvas, int density, boolean wired) { if (density < 1) { return null; } else { int borderLength = density + 1; FloatBuffer vertices = FloatBuffer.allocate(6 * borderLength * borderLength * 4); FloatBuffer normals = FloatBuffer.allocate(6 * borderLength * borderLength * 4); IntBuffer indices = IntBuffer.allocate(6 * 6 * density * density); IntBuffer wireIndices = IntBuffer.allocate(8 * 6 * density * density); int shift = 0; for (int axes = 0; axes < 3; axes++) { for (int orientation : new int[] {-1, 1}) { float[] normal = getVectorPermutation(axes, 0, 0, orientation); for (int i = 0; i < borderLength; i++) { for (int j = 0; j < borderLength; j++) { float s = (2f * i) / density - 1f; float t = (2f * j) / density - 1f; vertices.put(getVectorPermutation(axes, s, t, orientation)); normals.put(normal); } } for (int i = 0; i < density; i++) { for (int j = 0; j < density; j++) { int index = shift + j + i * borderLength; indices.put(index); indices.put(index + 1); indices.put(index + borderLength); indices.put(index + 1); indices.put(index + borderLength + 1); indices.put(index + borderLength); wireIndices.put(index); wireIndices.put(index + 1); wireIndices.put(index + 1); wireIndices.put(index + borderLength + 1); wireIndices.put(index + borderLength + 1); wireIndices.put(index + borderLength); wireIndices.put(index + borderLength); wireIndices.put(index); } } shift += borderLength * borderLength; } } vertices.rewind(); normals.rewind(); indices.rewind(); BuffersManager bm = canvas.getBuffersManager(); final ElementsBuffer verticesBuffer = bm.createElementsBuffer(); final ElementsBuffer normalsBuffer = bm.createElementsBuffer(); final IndicesBuffer indicesBuffer = bm.createIndicesBuffer(); verticesBuffer.setData(vertices, VERTEX_SIZE); normalsBuffer.setData(normals, VERTEX_SIZE); indicesBuffer.setData(indices); DefaultGeometry geometry = new DefaultGeometry(); geometry.setFaceCullingMode(Geometry.FaceCullingMode.BOTH); geometry.setFillDrawingMode(Geometry.FillDrawingMode.TRIANGLES); geometry.setVertices(verticesBuffer); geometry.setNormals(normalsBuffer); geometry.setIndices(indicesBuffer); if (wired) { final IndicesBuffer wireIndicesBuffer = bm.createIndicesBuffer(); wireIndicesBuffer.setData(wireIndices); geometry.setWireIndices(wireIndicesBuffer); geometry.setLineDrawingMode(Geometry.LineDrawingMode.SEGMENTS); geometry.setPolygonOffsetMode(true); } return geometry; } } /** * Return a permutation of the [s; t; u] vector. * @param permutation the permutation factor. * @param s x coordinate of the given vector. * @param t y coordinate of the given vector. * @param u z coordinate of the given vector. * @return a permutation of the [s; t; u] vector. */ private static float[] getVectorPermutation(int permutation, float s, float t, float u) { switch (permutation % 3) { case 0: return new float[] {s, t, u, 1}; case 1: return new float[] {u, s, t, 1}; case 2: return new float[] {t, u, s, 1}; default: return null; } } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/utils/shapes/geometry/SphereFactory.java000066400000000000000000000126231212506735300321470ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2011-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.utils.shapes.geometry; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import org.scilab.forge.scirenderer.shapes.geometry.DefaultGeometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import java.nio.FloatBuffer; import java.nio.IntBuffer; /** * @author Pierre Lando */ public final class SphereFactory { private static SphereFactory singleton; private SphereFactory() { } public static SphereFactory getSingleton() { if (singleton == null) { singleton = new SphereFactory(); } return singleton; } /** * Create a sphere geometry with classic longitude / latitude division. * @param canvas the canvas where the geometry will be created. * @param radius the sphere radius. * @param givenLatitude number of division in latitude. * @param givenLongitude number of division in longitude. * @return a sphere geometry with classic longitude / latitude division. */ public Geometry create(Canvas canvas, Float radius, int givenLatitude, int givenLongitude) { int latitude; int longitude; if (givenLatitude < 3) { latitude = 3; } else { latitude = givenLatitude; } if (givenLongitude < 4) { longitude = 4; } else { longitude = givenLongitude; } ElementsBuffer vertexBuffer = canvas.getBuffersManager().createElementsBuffer(); vertexBuffer.setData(createVertexData(radius, latitude, longitude), 4); IndicesBuffer indicesBuffer = canvas.getBuffersManager().createIndicesBuffer(); indicesBuffer.setData(createIndicesData(latitude, longitude)); DefaultGeometry geometry = new DefaultGeometry(); geometry.setFillDrawingMode(Geometry.FillDrawingMode.TRIANGLES); geometry.setVertices(vertexBuffer); geometry.setIndices(indicesBuffer); return geometry; } private IntBuffer createIndicesData(int latitudeResolution, int longitudeResolution) { int indexNumber = 6 * (latitudeResolution - 3) * longitudeResolution + 6 * longitudeResolution; IntBuffer indexBuffer = IntBuffer.allocate(indexNumber); indexBuffer.rewind(); for (int i = 0; i < longitudeResolution; i++) { indexBuffer.put(0); indexBuffer.put(1 + i); indexBuffer.put(1 + (i + 1) % longitudeResolution); } for (int latitude = 1; latitude < latitudeResolution - 2; latitude++) { for (int longitude = 0; longitude < longitudeResolution; longitude++) { int aIndex = 1 + longitude + (latitude - 1) * longitudeResolution; int bIndex = 1 + ((longitude + 1) % longitudeResolution) + (latitude - 1) * longitudeResolution; int cIndex = 1 + ((longitude + 1) % longitudeResolution) + latitude * longitudeResolution; int dIndex = 1 + longitude + latitude * longitudeResolution; indexBuffer.put(aIndex); indexBuffer.put(bIndex); indexBuffer.put(cIndex); indexBuffer.put(aIndex); indexBuffer.put(cIndex); indexBuffer.put(dIndex); } } int lastVertexIndex = (latitudeResolution - 2) * longitudeResolution + 2 - 1; for (int i = 0; i < longitudeResolution; i++) { indexBuffer.put(lastVertexIndex); indexBuffer.put(lastVertexIndex - longitudeResolution + i); indexBuffer.put(lastVertexIndex - longitudeResolution + (i + 1) % longitudeResolution); } indexBuffer.rewind(); return indexBuffer; } private FloatBuffer createVertexData(Float radius, int latitudeResolution, int longitudeResolution) { int vertexNumber = (latitudeResolution - 2) * longitudeResolution + 2; FloatBuffer dataBuffer = FloatBuffer.allocate(vertexNumber * 4); dataBuffer.rewind(); dataBuffer.put(new float[] {0, 0, radius, 1}); for (int latitude = 1; latitude < latitudeResolution - 1; latitude++) { double latitudeAngle = latitude * Math.PI / (latitudeResolution - 1); float z = (float) (radius * Math.cos(latitudeAngle)); float discRadius = (float) (radius * Math.sin(latitudeAngle)); for (int longitude = 0; longitude < longitudeResolution; longitude++) { double longitudeAngle = longitude * 2 * Math.PI / longitudeResolution; float x = (float) (discRadius * Math.cos(longitudeAngle)); float y = (float) (discRadius * Math.sin(longitudeAngle)); dataBuffer.put(x); dataBuffer.put(y); dataBuffer.put(z); dataBuffer.put(1); } } dataBuffer.put(new float[] {0, 0, -radius, 1}); dataBuffer.rewind(); return dataBuffer; } } scirenderer-1.1.0/src/org/scilab/forge/scirenderer/utils/shapes/geometry/TetrahedronFactory.java000066400000000000000000000113051212506735300331740ustar00rootroot00000000000000/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) 2009-2011 - DIGITEO - Pierre Lando * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt */ package org.scilab.forge.scirenderer.utils.shapes.geometry; import org.scilab.forge.scirenderer.Canvas; import org.scilab.forge.scirenderer.buffers.ElementsBuffer; import org.scilab.forge.scirenderer.buffers.IndicesBuffer; import org.scilab.forge.scirenderer.shapes.geometry.DefaultGeometry; import org.scilab.forge.scirenderer.shapes.geometry.Geometry; import org.scilab.forge.scirenderer.tranformations.Vector3d; import java.nio.FloatBuffer; import java.nio.IntBuffer; /** * An utility class to create a tetrahedron. * @author Pierre Lando */ public final class TetrahedronFactory { private static final int ELEMENTS_SIZE = 4; private static final Vector3d A = new Vector3d(+1, +1, +1); // Point #0 private static final Vector3d B = new Vector3d(+1, -1, -1); // Point #1 private static final Vector3d C = new Vector3d(-1, +1, -1); // Point #2 private static final Vector3d D = new Vector3d(-1, -1, +1); // Point #3 /** * Private constructor. * This is an utility class. */ private TetrahedronFactory() { } /** * @param canvas the canvas where the buffers are created. * @return a Tetrahedron geometry. */ public static DefaultGeometry createTetrahedron(Canvas canvas) { Vector3d mab = A.plus(B).times(.5); // Point #4 Vector3d mac = A.plus(C).times(.5); // Point #5 Vector3d mad = A.plus(D).times(.5); // Point #6 Vector3d mbc = B.plus(C).times(.5); // Point #7 Vector3d mbd = B.plus(D).times(.5); // Point #8 Vector3d mcd = C.plus(D).times(.5); // Point #9 // Create vertices buffer. FloatBuffer vertices = FloatBuffer.allocate(10 * ELEMENTS_SIZE); vertices.rewind(); vertices.put(A.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(B.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(C.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(D.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(mab.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(mac.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(mad.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(mbc.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(mbd.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.put(mcd.getDataAsFloatArray(ELEMENTS_SIZE)); vertices.rewind(); // 4 triangles per faces. // 4 faces. // 3 indices by triangles. IntBuffer indices = IntBuffer.allocate(48); indices.rewind(); indices.put(new int[]{ 0, 4, 5, 4, 1, 7, 5, 7, 2, 7, 5, 4, 0, 5, 6, 5, 2, 9, 6, 9, 3, 9, 6, 5, 0, 6, 4, 6, 3, 8, 4, 8, 1, 8, 4, 6, 8, 9, 7, 9, 8, 3, 7, 1, 8, 2, 7, 9 }); indices.rewind(); IntBuffer edgesIndices = IntBuffer.allocate(48); edgesIndices.rewind(); edgesIndices.put(new int[]{ 0, 4, 4, 1, 0, 5, 5, 2, 0, 6, 6, 3, 4, 5, 5, 6, 6, 4, 1, 7, 7, 2, 2, 9, 9, 3, 3, 8, 8, 1, 4, 7, 7, 5, 5, 9, 9, 6, 6, 8, 8, 4, 7, 9, 9, 8, 8, 7 }); edgesIndices.rewind(); canvas.getBuffersManager().createElementsBuffer(); ElementsBuffer vertexBuffer = canvas.getBuffersManager().createElementsBuffer(); IndicesBuffer indicesBuffer = canvas.getBuffersManager().createIndicesBuffer(); IndicesBuffer edgesIndicesBuffer = canvas.getBuffersManager().createIndicesBuffer(); vertexBuffer.setData(vertices, ELEMENTS_SIZE); indicesBuffer.setData(indices); edgesIndicesBuffer.setData(edgesIndices); DefaultGeometry geometry = new DefaultGeometry(); geometry.setFillDrawingMode(Geometry.FillDrawingMode.TRIANGLES); geometry.setLineDrawingMode(Geometry.LineDrawingMode.SEGMENTS); geometry.setPolygonOffsetMode(true); geometry.setWireIndices(edgesIndicesBuffer); geometry.setIndices(indicesBuffer); geometry.setVertices(vertexBuffer); return geometry; } }