├── .gitignore ├── .idea ├── compiler.xml ├── description.html ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── uiDesigner.xml └── vcs.xml ├── JavaFX 3D.iml ├── LICENSE ├── README.md └── src ├── gc └── tutorial │ ├── chapt1 │ └── Sphere3D.java │ ├── chapt10 │ └── SelfIllumination.java │ ├── chapt11 │ └── BumpMaps.java │ ├── chapt12 │ └── DepthBuffer.java │ ├── chapt13 │ └── Earth.java │ ├── chapt14 │ └── DetailedEarth.java │ ├── chapt15 │ └── SpinningEarth.java │ ├── chapt16 │ └── Galaxy.java │ ├── chapt17 │ └── GalaxyWithSlider.java │ ├── chapt2 │ └── Camera3D.java │ ├── chapt3 │ └── Rotation3D.java │ ├── chapt4 │ └── Rotation3DWithMouse.java │ ├── chapt5 │ └── MoreMouseControl.java │ ├── chapt6 │ └── Texture.java │ ├── chapt7 │ └── Reflection.java │ ├── chapt8 │ └── Lighting.java │ └── chapt9 │ └── MovingLights.java └── resources ├── earth ├── earth-d.jpg ├── earth-l.jpg ├── earth-n.jpg └── earth-s.jpg ├── galaxy └── galaxy.jpg ├── illuminati2.jpg ├── spec.jpg └── wood.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | .idea/workspace.xml -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/description.html: -------------------------------------------------------------------------------- 1 | Simple JavaFX 2.0 application that includes simple .fxml file with attached controller and Main class to quick start. Artifact to build JavaFX application is provided. 2 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /JavaFX 3D.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## JavaFX 3D Tutorial Code 2 | Tutorial code collection for my course in [Genuine Coder YouTube Channel](https://www.youtube.com/playlist?list=PLhs1urmduZ295Ryetga7CNOqDymN_rhB_) 3 | 4 | #### [Tutorial Index](http://genuinecoder.com/javafx-3d) 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt1/Sphere3D.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt1; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Camera; 5 | import javafx.scene.Group; 6 | import javafx.scene.PerspectiveCamera; 7 | import javafx.scene.Scene; 8 | import javafx.scene.input.KeyEvent; 9 | import javafx.scene.paint.Color; 10 | import javafx.scene.shape.Sphere; 11 | import javafx.stage.Stage; 12 | 13 | /** 14 | * @author afsal villan 15 | * @version 1.0 16 | * 17 | * http://www.genuinecoder.com 18 | */ 19 | public class Sphere3D extends Application { 20 | 21 | private static final int WIDTH = 1400; 22 | private static final int HEIGHT = 800; 23 | 24 | @Override 25 | public void start(Stage primaryStage) { 26 | Sphere sphere = new Sphere(50); 27 | 28 | Group group = new Group(); 29 | group.getChildren().add(sphere); 30 | 31 | Camera camera = new PerspectiveCamera(); 32 | Scene scene = new Scene(group, WIDTH, HEIGHT); 33 | scene.setFill(Color.SILVER); 34 | scene.setCamera(camera); 35 | 36 | sphere.translateXProperty().set(WIDTH / 2); 37 | sphere.translateYProperty().set(HEIGHT / 2); 38 | 39 | primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> { 40 | switch (event.getCode()) { 41 | case W: 42 | sphere.translateZProperty().set(sphere.getTranslateZ() + 100); 43 | break; 44 | case S: 45 | sphere.translateZProperty().set(sphere.getTranslateZ() - 100); 46 | break; 47 | } 48 | }); 49 | 50 | primaryStage.setTitle("Genuine Coder"); 51 | primaryStage.setScene(scene); 52 | primaryStage.show(); 53 | } 54 | 55 | 56 | public static void main(String[] args) { 57 | launch(args); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt10/SelfIllumination.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt10; 2 | 3 | import javafx.animation.AnimationTimer; 4 | import javafx.application.Application; 5 | import javafx.beans.property.DoubleProperty; 6 | import javafx.beans.property.SimpleDoubleProperty; 7 | import javafx.scene.Camera; 8 | import javafx.scene.Group; 9 | import javafx.scene.Node; 10 | import javafx.scene.PerspectiveCamera; 11 | import javafx.scene.PointLight; 12 | import javafx.scene.Scene; 13 | import javafx.scene.image.Image; 14 | import javafx.scene.input.KeyEvent; 15 | import javafx.scene.input.ScrollEvent; 16 | import javafx.scene.paint.Color; 17 | import javafx.scene.paint.PhongMaterial; 18 | import javafx.scene.shape.Box; 19 | import javafx.scene.shape.Sphere; 20 | import javafx.scene.transform.Rotate; 21 | import javafx.scene.transform.Transform; 22 | import javafx.scene.transform.Translate; 23 | import javafx.stage.Stage; 24 | 25 | /** 26 | * @author afsal villan 27 | * @version 1.0 28 | * 29 | * http://www.genuinecoder.com 30 | */ 31 | public class SelfIllumination extends Application { 32 | 33 | private static final float WIDTH = 1400; 34 | private static final float HEIGHT = 1000; 35 | 36 | private double anchorX, anchorY; 37 | private double anchorAngleX = 0; 38 | private double anchorAngleY = 0; 39 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 40 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 41 | private final PointLight pointLight = new PointLight(); 42 | 43 | @Override 44 | public void start(Stage primaryStage) { 45 | Box box = prepareBox(); 46 | 47 | SmartGroup group = new SmartGroup(); 48 | group.getChildren().add(box); 49 | // group.getChildren().addAll(prepareLightSource()); 50 | // group.getChildren().add(new AmbientLight()); 51 | group.getChildren().add(new PointLight()); 52 | 53 | Camera camera = new PerspectiveCamera(true); 54 | camera.setNearClip(1); 55 | camera.setFarClip(1000); 56 | camera.translateZProperty().set(-200); 57 | 58 | Scene scene = new Scene(group, WIDTH, HEIGHT); 59 | scene.setFill(Color.SILVER); 60 | scene.setCamera(camera); 61 | 62 | group.translateXProperty().set(0); 63 | group.translateYProperty().set(0); 64 | group.translateZProperty().set(0); 65 | 66 | initMouseControl(group, scene, primaryStage); 67 | 68 | primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> { 69 | switch (event.getCode()) { 70 | case W: 71 | group.translateZProperty().set(group.getTranslateZ() + 100); 72 | break; 73 | case S: 74 | group.translateZProperty().set(group.getTranslateZ() - 100); 75 | break; 76 | case Q: 77 | group.rotateByX(10); 78 | break; 79 | case E: 80 | group.rotateByX(-10); 81 | break; 82 | case NUMPAD6: 83 | group.rotateByY(10); 84 | break; 85 | case NUMPAD4: 86 | group.rotateByY(-10); 87 | break; 88 | } 89 | }); 90 | 91 | primaryStage.setTitle("Genuine Coder"); 92 | primaryStage.setScene(scene); 93 | primaryStage.show(); 94 | 95 | AnimationTimer timer = new AnimationTimer() { 96 | @Override 97 | public void handle(long now) { 98 | pointLight.setRotate(pointLight.getRotate() + 1); 99 | } 100 | }; 101 | timer.start(); 102 | } 103 | 104 | private Node[] prepareLightSource() { 105 | pointLight.setColor(Color.RED); 106 | pointLight.getTransforms().add(new Translate(0, -50, 100)); 107 | pointLight.setRotationAxis(Rotate.X_AXIS); 108 | 109 | Sphere sphere = new Sphere(2); 110 | sphere.getTransforms().setAll(pointLight.getTransforms()); 111 | sphere.rotateProperty().bind(pointLight.rotateProperty()); 112 | sphere.rotationAxisProperty().bind(pointLight.rotationAxisProperty()); 113 | 114 | return new Node[]{pointLight, sphere}; 115 | } 116 | 117 | private Box prepareBox() { 118 | PhongMaterial material = new PhongMaterial(); 119 | material.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/wood.jpg"))); 120 | 121 | //Set self illumination map 122 | material.setSelfIlluminationMap(new Image(getClass().getResourceAsStream("/resources/illuminati2.jpg"))); 123 | Box box = new Box(100, 20, 50); 124 | box.setMaterial(material); 125 | return box; 126 | } 127 | 128 | private void initMouseControl(SmartGroup group, Scene scene, Stage stage) { 129 | Rotate xRotate; 130 | Rotate yRotate; 131 | group.getTransforms().addAll( 132 | xRotate = new Rotate(0, Rotate.X_AXIS), 133 | yRotate = new Rotate(0, Rotate.Y_AXIS) 134 | ); 135 | xRotate.angleProperty().bind(angleX); 136 | yRotate.angleProperty().bind(angleY); 137 | 138 | scene.setOnMousePressed(event -> { 139 | anchorX = event.getSceneX(); 140 | anchorY = event.getSceneY(); 141 | anchorAngleX = angleX.get(); 142 | anchorAngleY = angleY.get(); 143 | }); 144 | 145 | scene.setOnMouseDragged(event -> { 146 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 147 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 148 | }); 149 | 150 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 151 | double delta = event.getDeltaY(); 152 | group.translateZProperty().set(group.getTranslateZ() + delta); 153 | }); 154 | } 155 | 156 | public static void main(String[] args) { 157 | launch(args); 158 | } 159 | 160 | class SmartGroup extends Group { 161 | 162 | Rotate r; 163 | Transform t = new Rotate(); 164 | 165 | void rotateByX(int ang) { 166 | r = new Rotate(ang, Rotate.X_AXIS); 167 | t = t.createConcatenation(r); 168 | this.getTransforms().clear(); 169 | this.getTransforms().addAll(t); 170 | } 171 | 172 | void rotateByY(int ang) { 173 | r = new Rotate(ang, Rotate.Y_AXIS); 174 | t = t.createConcatenation(r); 175 | this.getTransforms().clear(); 176 | this.getTransforms().addAll(t); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt11/BumpMaps.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt11; 2 | 3 | import javafx.animation.AnimationTimer; 4 | import javafx.application.Application; 5 | import javafx.beans.property.DoubleProperty; 6 | import javafx.beans.property.SimpleDoubleProperty; 7 | import javafx.scene.Camera; 8 | import javafx.scene.Group; 9 | import javafx.scene.Node; 10 | import javafx.scene.PerspectiveCamera; 11 | import javafx.scene.PointLight; 12 | import javafx.scene.Scene; 13 | import javafx.scene.image.Image; 14 | import javafx.scene.input.KeyEvent; 15 | import javafx.scene.input.ScrollEvent; 16 | import javafx.scene.paint.Color; 17 | import javafx.scene.paint.PhongMaterial; 18 | import javafx.scene.shape.Box; 19 | import javafx.scene.shape.Sphere; 20 | import javafx.scene.transform.Rotate; 21 | import javafx.scene.transform.Transform; 22 | import javafx.scene.transform.Translate; 23 | import javafx.stage.Stage; 24 | 25 | /** 26 | * @author afsal villan 27 | * @version 1.0 28 | * 29 | * http://www.genuinecoder.com 30 | */ 31 | public class BumpMaps extends Application { 32 | 33 | private static final float WIDTH = 1400; 34 | private static final float HEIGHT = 1000; 35 | private final PointLight pointLight = new PointLight(); 36 | 37 | private double anchorX, anchorY; 38 | private double anchorAngleX = 0; 39 | private double anchorAngleY = 0; 40 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 41 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 42 | 43 | @Override 44 | public void start(Stage primaryStage) { 45 | Box box = prepareBox(); 46 | 47 | SmartGroup group = new SmartGroup(); 48 | group.getChildren().add(box); 49 | group.getChildren().addAll(prepareLightSource()); 50 | // group.getChildren().add(new AmbientLight()); 51 | 52 | Camera camera = new PerspectiveCamera(true); 53 | camera.setNearClip(1); 54 | camera.setFarClip(1000); 55 | camera.translateZProperty().set(-200); 56 | 57 | Scene scene = new Scene(group, WIDTH, HEIGHT); 58 | scene.setFill(Color.SILVER); 59 | scene.setCamera(camera); 60 | 61 | group.translateXProperty().set(0); 62 | group.translateYProperty().set(0); 63 | group.translateZProperty().set(0); 64 | 65 | initMouseControl(group, scene, primaryStage); 66 | 67 | primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> { 68 | switch (event.getCode()) { 69 | case W: 70 | group.translateZProperty().set(group.getTranslateZ() + 100); 71 | break; 72 | case S: 73 | group.translateZProperty().set(group.getTranslateZ() - 100); 74 | break; 75 | case Q: 76 | group.rotateByX(10); 77 | break; 78 | case E: 79 | group.rotateByX(-10); 80 | break; 81 | case NUMPAD6: 82 | group.rotateByY(10); 83 | break; 84 | case NUMPAD4: 85 | group.rotateByY(-10); 86 | break; 87 | } 88 | }); 89 | 90 | primaryStage.setTitle("Genuine Coder"); 91 | primaryStage.setScene(scene); 92 | primaryStage.show(); 93 | 94 | AnimationTimer timer = new AnimationTimer() { 95 | @Override 96 | public void handle(long now) { 97 | pointLight.setRotate(pointLight.getRotate() + 1); 98 | } 99 | }; 100 | timer.start(); 101 | } 102 | 103 | private Node[] prepareLightSource() { 104 | pointLight.setColor(Color.RED); 105 | pointLight.getTransforms().add(new Translate(0, -50, 100)); 106 | pointLight.setRotationAxis(Rotate.X_AXIS); 107 | 108 | Sphere sphere = new Sphere(2); 109 | sphere.getTransforms().setAll(pointLight.getTransforms()); 110 | sphere.rotateProperty().bind(pointLight.rotateProperty()); 111 | sphere.rotationAxisProperty().bind(pointLight.rotationAxisProperty()); 112 | 113 | return new Node[]{pointLight, sphere}; 114 | } 115 | 116 | private Box prepareBox() { 117 | PhongMaterial material = new PhongMaterial(); 118 | material.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/wood.jpg"))); 119 | material.setBumpMap(new Image(getClass().getResourceAsStream("/resources/illuminati2.jpg"))); 120 | Box box = new Box(100, 20, 50); 121 | box.setMaterial(material); 122 | return box; 123 | } 124 | 125 | private void initMouseControl(SmartGroup group, Scene scene, Stage stage) { 126 | Rotate xRotate; 127 | Rotate yRotate; 128 | group.getTransforms().addAll( 129 | xRotate = new Rotate(0, Rotate.X_AXIS), 130 | yRotate = new Rotate(0, Rotate.Y_AXIS) 131 | ); 132 | xRotate.angleProperty().bind(angleX); 133 | yRotate.angleProperty().bind(angleY); 134 | 135 | scene.setOnMousePressed(event -> { 136 | anchorX = event.getSceneX(); 137 | anchorY = event.getSceneY(); 138 | anchorAngleX = angleX.get(); 139 | anchorAngleY = angleY.get(); 140 | }); 141 | 142 | scene.setOnMouseDragged(event -> { 143 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 144 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 145 | }); 146 | 147 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 148 | double delta = event.getDeltaY(); 149 | group.translateZProperty().set(group.getTranslateZ() + delta); 150 | }); 151 | } 152 | 153 | public static void main(String[] args) { 154 | launch(args); 155 | } 156 | 157 | class SmartGroup extends Group { 158 | 159 | Rotate r; 160 | Transform t = new Rotate(); 161 | 162 | void rotateByX(int ang) { 163 | r = new Rotate(ang, Rotate.X_AXIS); 164 | t = t.createConcatenation(r); 165 | this.getTransforms().clear(); 166 | this.getTransforms().addAll(t); 167 | } 168 | 169 | void rotateByY(int ang) { 170 | r = new Rotate(ang, Rotate.Y_AXIS); 171 | t = t.createConcatenation(r); 172 | this.getTransforms().clear(); 173 | this.getTransforms().addAll(t); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt12/DepthBuffer.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt12; 2 | 3 | import javafx.animation.AnimationTimer; 4 | import javafx.application.Application; 5 | import javafx.beans.property.DoubleProperty; 6 | import javafx.beans.property.SimpleDoubleProperty; 7 | import javafx.scene.AmbientLight; 8 | import javafx.scene.Camera; 9 | import javafx.scene.Group; 10 | import javafx.scene.Node; 11 | import javafx.scene.PerspectiveCamera; 12 | import javafx.scene.PointLight; 13 | import javafx.scene.Scene; 14 | import javafx.scene.image.Image; 15 | import javafx.scene.input.KeyEvent; 16 | import javafx.scene.input.ScrollEvent; 17 | import javafx.scene.paint.Color; 18 | import javafx.scene.paint.PhongMaterial; 19 | import javafx.scene.shape.Box; 20 | import javafx.scene.shape.Sphere; 21 | import javafx.scene.transform.Rotate; 22 | import javafx.scene.transform.Transform; 23 | import javafx.scene.transform.Translate; 24 | import javafx.stage.Stage; 25 | 26 | /** 27 | * @author afsal villan 28 | * @version 1.0 29 | * 30 | * http://www.genuinecoder.com 31 | */ 32 | public class DepthBuffer extends Application { 33 | 34 | private static final float WIDTH = 1400; 35 | private static final float HEIGHT = 1000; 36 | 37 | private double anchorX, anchorY; 38 | private double anchorAngleX = 0; 39 | private double anchorAngleY = 0; 40 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 41 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 42 | private final PointLight pointLight = new PointLight(); 43 | 44 | @Override 45 | public void start(Stage primaryStage) { 46 | Box box = prepareBox(); 47 | 48 | SmartGroup group = new SmartGroup(); 49 | group.getChildren().add(box); 50 | group.getChildren().add(prepareSecondBox()); 51 | group.getChildren().add(new AmbientLight()); 52 | 53 | Camera camera = new PerspectiveCamera(true); 54 | camera.setNearClip(1); 55 | camera.setFarClip(1000); 56 | camera.translateZProperty().set(-200); 57 | 58 | Scene scene = new Scene(group, WIDTH, HEIGHT, true); 59 | scene.setFill(Color.SILVER); 60 | scene.setCamera(camera); 61 | 62 | group.translateXProperty().set(0); 63 | group.translateYProperty().set(0); 64 | group.translateZProperty().set(0); 65 | 66 | initMouseControl(group, scene, primaryStage); 67 | 68 | primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> { 69 | switch (event.getCode()) { 70 | case W: 71 | group.translateZProperty().set(group.getTranslateZ() + 100); 72 | break; 73 | case S: 74 | group.translateZProperty().set(group.getTranslateZ() - 100); 75 | break; 76 | case Q: 77 | group.rotateByX(10); 78 | break; 79 | case E: 80 | group.rotateByX(-10); 81 | break; 82 | case NUMPAD6: 83 | group.rotateByY(10); 84 | break; 85 | case NUMPAD4: 86 | group.rotateByY(-10); 87 | break; 88 | } 89 | }); 90 | 91 | primaryStage.setTitle("Genuine Coder"); 92 | primaryStage.setScene(scene); 93 | primaryStage.show(); 94 | 95 | AnimationTimer timer = new AnimationTimer() { 96 | @Override 97 | public void handle(long now) { 98 | pointLight.setRotate(pointLight.getRotate() + 1); 99 | } 100 | }; 101 | timer.start(); 102 | } 103 | 104 | private Node prepareSecondBox() { 105 | PhongMaterial material = new PhongMaterial(); 106 | material.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/wood.jpg"))); 107 | Box box = new Box(20, 100, 100); 108 | box.setMaterial(material); 109 | return box; 110 | } 111 | 112 | private Box prepareBox() { 113 | PhongMaterial material = new PhongMaterial(); 114 | material.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/wood.jpg"))); 115 | Box box = new Box(100, 20, 50); 116 | box.setMaterial(material); 117 | return box; 118 | } 119 | 120 | private void initMouseControl(SmartGroup group, Scene scene, Stage stage) { 121 | Rotate xRotate; 122 | Rotate yRotate; 123 | group.getTransforms().addAll( 124 | xRotate = new Rotate(0, Rotate.X_AXIS), 125 | yRotate = new Rotate(0, Rotate.Y_AXIS) 126 | ); 127 | xRotate.angleProperty().bind(angleX); 128 | yRotate.angleProperty().bind(angleY); 129 | 130 | scene.setOnMousePressed(event -> { 131 | anchorX = event.getSceneX(); 132 | anchorY = event.getSceneY(); 133 | anchorAngleX = angleX.get(); 134 | anchorAngleY = angleY.get(); 135 | }); 136 | 137 | scene.setOnMouseDragged(event -> { 138 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 139 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 140 | }); 141 | 142 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 143 | double delta = event.getDeltaY(); 144 | group.translateZProperty().set(group.getTranslateZ() + delta); 145 | }); 146 | } 147 | 148 | public static void main(String[] args) { 149 | launch(args); 150 | } 151 | 152 | class SmartGroup extends Group { 153 | 154 | Rotate r; 155 | Transform t = new Rotate(); 156 | 157 | void rotateByX(int ang) { 158 | r = new Rotate(ang, Rotate.X_AXIS); 159 | t = t.createConcatenation(r); 160 | this.getTransforms().clear(); 161 | this.getTransforms().addAll(t); 162 | } 163 | 164 | void rotateByY(int ang) { 165 | r = new Rotate(ang, Rotate.Y_AXIS); 166 | t = t.createConcatenation(r); 167 | this.getTransforms().clear(); 168 | this.getTransforms().addAll(t); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt13/Earth.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt13; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Camera; 5 | import javafx.scene.Group; 6 | import javafx.scene.Node; 7 | import javafx.scene.PerspectiveCamera; 8 | import javafx.scene.Scene; 9 | import javafx.scene.image.Image; 10 | import javafx.scene.paint.Color; 11 | import javafx.scene.paint.PhongMaterial; 12 | import javafx.scene.shape.Sphere; 13 | import javafx.stage.Stage; 14 | 15 | /** 16 | * @author afsal villan 17 | * @version 1.0 18 | * 19 | * http://www.genuinecoder.com 20 | */ 21 | public class Earth extends Application { 22 | 23 | private static final float WIDTH = 1400; 24 | private static final float HEIGHT = 1000; 25 | 26 | @Override 27 | public void start(Stage primaryStage) { 28 | Camera camera = new PerspectiveCamera(true); 29 | camera.setNearClip(1); 30 | camera.setFarClip(1000); 31 | camera.translateZProperty().set(-1000); 32 | 33 | Group world = new Group(); 34 | world.getChildren().add(prepareEarth()); 35 | 36 | Scene scene = new Scene(world, WIDTH, HEIGHT, true); 37 | scene.setFill(Color.SILVER); 38 | scene.setCamera(camera); 39 | 40 | primaryStage.setTitle("Genuine Coder"); 41 | primaryStage.setScene(scene); 42 | primaryStage.show(); 43 | } 44 | 45 | private Node prepareEarth() { 46 | PhongMaterial earthMaterial = new PhongMaterial(); 47 | earthMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-d.jpg"))); 48 | Sphere sphere = new Sphere(150); 49 | sphere.setMaterial(earthMaterial); 50 | return sphere; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt14/DetailedEarth.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt14; 2 | 3 | import javafx.application.Application; 4 | import javafx.beans.property.DoubleProperty; 5 | import javafx.beans.property.SimpleDoubleProperty; 6 | import javafx.scene.Camera; 7 | import javafx.scene.Group; 8 | import javafx.scene.Node; 9 | import javafx.scene.PerspectiveCamera; 10 | import javafx.scene.Scene; 11 | import javafx.scene.image.Image; 12 | import javafx.scene.input.ScrollEvent; 13 | import javafx.scene.paint.Color; 14 | import javafx.scene.paint.PhongMaterial; 15 | import javafx.scene.shape.Sphere; 16 | import javafx.scene.transform.Rotate; 17 | import javafx.stage.Stage; 18 | 19 | /** 20 | * @author afsal villan 21 | * @version 1.0 22 | * 23 | * http://www.genuinecoder.com 24 | */ 25 | public class DetailedEarth extends Application { 26 | 27 | private static final float WIDTH = 1400; 28 | private static final float HEIGHT = 1000; 29 | 30 | private double anchorX, anchorY; 31 | private double anchorAngleX = 0; 32 | private double anchorAngleY = 0; 33 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 34 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 35 | 36 | @Override 37 | public void start(Stage primaryStage) { 38 | Camera camera = new PerspectiveCamera(true); 39 | camera.setNearClip(1); 40 | camera.setFarClip(1000); 41 | camera.translateZProperty().set(-1000); 42 | 43 | Group world = new Group(); 44 | world.getChildren().add(prepareEarth()); 45 | 46 | Scene scene = new Scene(world, WIDTH, HEIGHT, true); 47 | scene.setFill(Color.SILVER); 48 | scene.setCamera(camera); 49 | 50 | initMouseControl(world, scene, primaryStage); 51 | 52 | primaryStage.setTitle("Genuine Coder"); 53 | primaryStage.setScene(scene); 54 | primaryStage.show(); 55 | } 56 | 57 | private Node prepareEarth() { 58 | PhongMaterial earthMaterial = new PhongMaterial(); 59 | earthMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-d.jpg"))); 60 | earthMaterial.setSelfIlluminationMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-l.jpg"))); 61 | earthMaterial.setSpecularMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-s.jpg"))); 62 | earthMaterial.setBumpMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-n.jpg"))); 63 | 64 | Sphere sphere = new Sphere(150); 65 | sphere.setMaterial(earthMaterial); 66 | return sphere; 67 | } 68 | 69 | private void initMouseControl(Group group, Scene scene, Stage stage) { 70 | Rotate xRotate; 71 | Rotate yRotate; 72 | group.getTransforms().addAll( 73 | xRotate = new Rotate(0, Rotate.X_AXIS), 74 | yRotate = new Rotate(0, Rotate.Y_AXIS) 75 | ); 76 | xRotate.angleProperty().bind(angleX); 77 | yRotate.angleProperty().bind(angleY); 78 | 79 | scene.setOnMousePressed(event -> { 80 | anchorX = event.getSceneX(); 81 | anchorY = event.getSceneY(); 82 | anchorAngleX = angleX.get(); 83 | anchorAngleY = angleY.get(); 84 | }); 85 | 86 | scene.setOnMouseDragged(event -> { 87 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 88 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 89 | }); 90 | 91 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 92 | double delta = event.getDeltaY(); 93 | group.translateZProperty().set(group.getTranslateZ() + delta); 94 | }); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt15/SpinningEarth.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt15; 2 | 3 | import javafx.animation.AnimationTimer; 4 | import javafx.application.Application; 5 | import javafx.beans.property.DoubleProperty; 6 | import javafx.beans.property.SimpleDoubleProperty; 7 | import javafx.scene.Camera; 8 | import javafx.scene.Group; 9 | import javafx.scene.Node; 10 | import javafx.scene.PerspectiveCamera; 11 | import javafx.scene.Scene; 12 | import javafx.scene.image.Image; 13 | import javafx.scene.input.ScrollEvent; 14 | import javafx.scene.paint.Color; 15 | import javafx.scene.paint.PhongMaterial; 16 | import javafx.scene.shape.Sphere; 17 | import javafx.scene.transform.Rotate; 18 | import javafx.stage.Stage; 19 | 20 | /** 21 | * @author afsal villan 22 | * @version 1.0 23 | * 24 | * http://www.genuinecoder.com 25 | */ 26 | public class SpinningEarth extends Application { 27 | 28 | private static final float WIDTH = 1400; 29 | private static final float HEIGHT = 1000; 30 | 31 | private double anchorX, anchorY; 32 | private double anchorAngleX = 0; 33 | private double anchorAngleY = 0; 34 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 35 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 36 | 37 | private final Sphere sphere = new Sphere(150); 38 | 39 | 40 | @Override 41 | public void start(Stage primaryStage) { 42 | Camera camera = new PerspectiveCamera(true); 43 | camera.setNearClip(1); 44 | camera.setFarClip(10000); 45 | camera.translateZProperty().set(-1000); 46 | 47 | Group world = new Group(); 48 | world.getChildren().add(prepareEarth()); 49 | 50 | Scene scene = new Scene(world, WIDTH, HEIGHT, true); 51 | scene.setFill(Color.SILVER); 52 | scene.setCamera(camera); 53 | 54 | initMouseControl(world, scene, primaryStage); 55 | 56 | primaryStage.setTitle("Genuine Coder"); 57 | primaryStage.setScene(scene); 58 | primaryStage.show(); 59 | 60 | prepareAnimation(); 61 | } 62 | 63 | private void prepareAnimation() { 64 | AnimationTimer timer = new AnimationTimer() { 65 | @Override 66 | public void handle(long now) { 67 | sphere.rotateProperty().set(sphere.getRotate() + 0.2); 68 | } 69 | }; 70 | timer.start(); 71 | } 72 | 73 | private Node prepareEarth() { 74 | PhongMaterial earthMaterial = new PhongMaterial(); 75 | earthMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-d.jpg"))); 76 | earthMaterial.setSelfIlluminationMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-l.jpg"))); 77 | earthMaterial.setSpecularMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-s.jpg"))); 78 | earthMaterial.setBumpMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-n.jpg"))); 79 | 80 | sphere.setRotationAxis(Rotate.Y_AXIS); 81 | sphere.setMaterial(earthMaterial); 82 | return sphere; 83 | } 84 | 85 | private void initMouseControl(Group group, Scene scene, Stage stage) { 86 | Rotate xRotate; 87 | Rotate yRotate; 88 | group.getTransforms().addAll( 89 | xRotate = new Rotate(0, Rotate.X_AXIS), 90 | yRotate = new Rotate(0, Rotate.Y_AXIS) 91 | ); 92 | xRotate.angleProperty().bind(angleX); 93 | yRotate.angleProperty().bind(angleY); 94 | 95 | scene.setOnMousePressed(event -> { 96 | anchorX = event.getSceneX(); 97 | anchorY = event.getSceneY(); 98 | anchorAngleX = angleX.get(); 99 | anchorAngleY = angleY.get(); 100 | }); 101 | 102 | scene.setOnMouseDragged(event -> { 103 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 104 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 105 | }); 106 | 107 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 108 | double delta = event.getDeltaY(); 109 | group.translateZProperty().set(group.getTranslateZ() + delta); 110 | }); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt16/Galaxy.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt16; 2 | 3 | import javafx.animation.AnimationTimer; 4 | import javafx.application.Application; 5 | import javafx.beans.property.DoubleProperty; 6 | import javafx.beans.property.SimpleDoubleProperty; 7 | import javafx.scene.Camera; 8 | import javafx.scene.Group; 9 | import javafx.scene.Node; 10 | import javafx.scene.PerspectiveCamera; 11 | import javafx.scene.Scene; 12 | import javafx.scene.image.Image; 13 | import javafx.scene.image.ImageView; 14 | import javafx.scene.input.ScrollEvent; 15 | import javafx.scene.paint.Color; 16 | import javafx.scene.paint.PhongMaterial; 17 | import javafx.scene.shape.Sphere; 18 | import javafx.scene.transform.Rotate; 19 | import javafx.scene.transform.Translate; 20 | import javafx.stage.Stage; 21 | 22 | /** 23 | * @author afsal villan 24 | * @version 1.0 25 | * 26 | * http://www.genuinecoder.com 27 | */ 28 | public class Galaxy extends Application { 29 | 30 | private static final float WIDTH = 1400; 31 | private static final float HEIGHT = 1000; 32 | 33 | private double anchorX, anchorY; 34 | private double anchorAngleX = 0; 35 | private double anchorAngleY = 0; 36 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 37 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 38 | 39 | private final Sphere sphere = new Sphere(150); 40 | 41 | 42 | @Override 43 | public void start(Stage primaryStage) { 44 | Camera camera = new PerspectiveCamera(true); 45 | camera.setNearClip(1); 46 | camera.setFarClip(10000); 47 | camera.translateZProperty().set(-1000); 48 | 49 | Group world = new Group(); 50 | world.getChildren().add(prepareEarth()); 51 | 52 | Group root = new Group(); 53 | root.getChildren().add(world); 54 | root.getChildren().add(prepareImageView()); 55 | 56 | Scene scene = new Scene(root, WIDTH, HEIGHT, true); 57 | scene.setFill(Color.SILVER); 58 | scene.setCamera(camera); 59 | 60 | initMouseControl(world, scene, primaryStage); 61 | 62 | primaryStage.setTitle("Genuine Coder"); 63 | primaryStage.setScene(scene); 64 | primaryStage.show(); 65 | 66 | prepareAnimation(); 67 | } 68 | 69 | private void prepareAnimation() { 70 | AnimationTimer timer = new AnimationTimer() { 71 | @Override 72 | public void handle(long now) { 73 | sphere.rotateProperty().set(sphere.getRotate() + 0.2); 74 | } 75 | }; 76 | timer.start(); 77 | } 78 | 79 | private ImageView prepareImageView() { 80 | Image image = new Image(getClass().getResourceAsStream("/resources/galaxy/galaxy.jpg")); 81 | ImageView imageView = new ImageView(image); 82 | imageView.setPreserveRatio(true); 83 | imageView.getTransforms().add(new Translate(-image.getWidth() / 2, -image.getHeight() / 2, 800)); 84 | return imageView; 85 | } 86 | 87 | private Node prepareEarth() { 88 | PhongMaterial earthMaterial = new PhongMaterial(); 89 | earthMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-d.jpg"))); 90 | earthMaterial.setSelfIlluminationMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-l.jpg"))); 91 | earthMaterial.setSpecularMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-s.jpg"))); 92 | earthMaterial.setBumpMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-n.jpg"))); 93 | 94 | sphere.setRotationAxis(Rotate.Y_AXIS); 95 | sphere.setMaterial(earthMaterial); 96 | return sphere; 97 | } 98 | 99 | private void initMouseControl(Group group, Scene scene, Stage stage) { 100 | Rotate xRotate; 101 | Rotate yRotate; 102 | group.getTransforms().addAll( 103 | xRotate = new Rotate(0, Rotate.X_AXIS), 104 | yRotate = new Rotate(0, Rotate.Y_AXIS) 105 | ); 106 | xRotate.angleProperty().bind(angleX); 107 | yRotate.angleProperty().bind(angleY); 108 | 109 | scene.setOnMousePressed(event -> { 110 | anchorX = event.getSceneX(); 111 | anchorY = event.getSceneY(); 112 | anchorAngleX = angleX.get(); 113 | anchorAngleY = angleY.get(); 114 | }); 115 | 116 | scene.setOnMouseDragged(event -> { 117 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 118 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 119 | }); 120 | 121 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 122 | double delta = event.getDeltaY(); 123 | group.translateZProperty().set(group.getTranslateZ() + delta); 124 | }); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt17/GalaxyWithSlider.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt17; 2 | 3 | import javafx.animation.AnimationTimer; 4 | import javafx.application.Application; 5 | import javafx.beans.property.DoubleProperty; 6 | import javafx.beans.property.SimpleDoubleProperty; 7 | import javafx.scene.Camera; 8 | import javafx.scene.Group; 9 | import javafx.scene.Node; 10 | import javafx.scene.PerspectiveCamera; 11 | import javafx.scene.Scene; 12 | import javafx.scene.control.Slider; 13 | import javafx.scene.image.Image; 14 | import javafx.scene.image.ImageView; 15 | import javafx.scene.input.ScrollEvent; 16 | import javafx.scene.paint.Color; 17 | import javafx.scene.paint.PhongMaterial; 18 | import javafx.scene.shape.Sphere; 19 | import javafx.scene.transform.Rotate; 20 | import javafx.scene.transform.Translate; 21 | import javafx.stage.Stage; 22 | 23 | /** 24 | * @author afsal villan 25 | * @version 1.0 26 | * 27 | * http://www.genuinecoder.com 28 | */ 29 | public class GalaxyWithSlider extends Application { 30 | 31 | private static final float WIDTH = 1400; 32 | private static final float HEIGHT = 1000; 33 | 34 | private double anchorX, anchorY; 35 | private double anchorAngleX = 0; 36 | private double anchorAngleY = 0; 37 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 38 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 39 | 40 | private final Sphere sphere = new Sphere(150); 41 | 42 | 43 | @Override 44 | public void start(Stage primaryStage) { 45 | Camera camera = new PerspectiveCamera(true); 46 | camera.setNearClip(1); 47 | camera.setFarClip(10000); 48 | camera.translateZProperty().set(-1000); 49 | 50 | Group world = new Group(); 51 | world.getChildren().add(prepareEarth()); 52 | 53 | Slider slider = prepareSlider(); 54 | world.translateZProperty().bind(slider.valueProperty()); 55 | 56 | Group root = new Group(); 57 | root.getChildren().add(world); 58 | root.getChildren().add(prepareImageView()); 59 | root.getChildren().add(slider); 60 | 61 | Scene scene = new Scene(root, WIDTH, HEIGHT, true); 62 | scene.setFill(Color.SILVER); 63 | scene.setCamera(camera); 64 | 65 | initMouseControl(world, scene, primaryStage); 66 | 67 | primaryStage.setTitle("Genuine Coder"); 68 | primaryStage.setScene(scene); 69 | primaryStage.show(); 70 | 71 | prepareAnimation(); 72 | } 73 | 74 | private void prepareAnimation() { 75 | AnimationTimer timer = new AnimationTimer() { 76 | @Override 77 | public void handle(long now) { 78 | sphere.rotateProperty().set(sphere.getRotate() + 0.2); 79 | } 80 | }; 81 | timer.start(); 82 | } 83 | 84 | private ImageView prepareImageView() { 85 | Image image = new Image(GalaxyWithSlider.class.getResourceAsStream("/resources/galaxy/galaxy.jpg")); 86 | ImageView imageView = new ImageView(image); 87 | imageView.setPreserveRatio(true); 88 | imageView.getTransforms().add(new Translate(-image.getWidth() / 2, -image.getHeight() / 2, 800)); 89 | return imageView; 90 | } 91 | 92 | private Slider prepareSlider() { 93 | Slider slider = new Slider(); 94 | slider.setMax(800); 95 | slider.setMin(-400); 96 | slider.setPrefWidth(300d); 97 | slider.setLayoutX(-150); 98 | slider.setLayoutY(200); 99 | slider.setShowTickLabels(true); 100 | slider.setTranslateZ(5); 101 | slider.setStyle("-fx-base: black"); 102 | return slider; 103 | } 104 | 105 | private Node prepareEarth() { 106 | PhongMaterial earthMaterial = new PhongMaterial(); 107 | earthMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-d.jpg"))); 108 | earthMaterial.setSelfIlluminationMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-l.jpg"))); 109 | earthMaterial.setSpecularMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-s.jpg"))); 110 | earthMaterial.setBumpMap(new Image(getClass().getResourceAsStream("/resources/earth/earth-n.jpg"))); 111 | 112 | sphere.setRotationAxis(Rotate.Y_AXIS); 113 | sphere.setMaterial(earthMaterial); 114 | return sphere; 115 | } 116 | 117 | private void initMouseControl(Group group, Scene scene, Stage stage) { 118 | Rotate xRotate; 119 | Rotate yRotate; 120 | group.getTransforms().addAll( 121 | xRotate = new Rotate(0, Rotate.X_AXIS), 122 | yRotate = new Rotate(0, Rotate.Y_AXIS) 123 | ); 124 | xRotate.angleProperty().bind(angleX); 125 | yRotate.angleProperty().bind(angleY); 126 | 127 | scene.setOnMousePressed(event -> { 128 | anchorX = event.getSceneX(); 129 | anchorY = event.getSceneY(); 130 | anchorAngleX = angleX.get(); 131 | anchorAngleY = angleY.get(); 132 | }); 133 | 134 | scene.setOnMouseDragged(event -> { 135 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 136 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 137 | }); 138 | 139 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 140 | double delta = event.getDeltaY(); 141 | group.translateZProperty().set(group.getTranslateZ() + delta); 142 | }); 143 | } 144 | } -------------------------------------------------------------------------------- /src/gc/tutorial/chapt2/Camera3D.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt2; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Camera; 5 | import javafx.scene.Group; 6 | import javafx.scene.PerspectiveCamera; 7 | import javafx.scene.Scene; 8 | import javafx.scene.input.KeyEvent; 9 | import javafx.scene.paint.Color; 10 | import javafx.scene.shape.Sphere; 11 | import javafx.stage.Stage; 12 | 13 | /** 14 | * @author afsal villan 15 | * @version 1.0 16 | * 17 | * http://www.genuinecoder.com 18 | */ 19 | public class Camera3D extends Application { 20 | 21 | private static final int WIDTH = 1400; 22 | private static final int HEIGHT = 800; 23 | 24 | @Override 25 | public void start(Stage primaryStage) { 26 | Sphere sphere = new Sphere(50); 27 | 28 | Group group = new Group(); 29 | group.getChildren().add(sphere); 30 | 31 | Camera camera = new PerspectiveCamera(true); 32 | Scene scene = new Scene(group, WIDTH, HEIGHT); 33 | scene.setFill(Color.SILVER); 34 | scene.setCamera(camera); 35 | 36 | camera.translateZProperty().set(-500); 37 | 38 | camera.setNearClip(1); 39 | camera.setFarClip(1000); 40 | 41 | primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> { 42 | switch (event.getCode()) { 43 | case W: 44 | camera.translateZProperty().set(camera.getTranslateZ() + 100); 45 | break; 46 | case S: 47 | camera.translateZProperty().set(camera.getTranslateZ() - 100); 48 | break; 49 | } 50 | }); 51 | 52 | primaryStage.setTitle("Genuine Coder"); 53 | primaryStage.setScene(scene); 54 | primaryStage.show(); 55 | } 56 | 57 | 58 | public static void main(String[] args) { 59 | launch(args); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt3/Rotation3D.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt3; 2 | 3 | import javafx.application.Application; 4 | import javafx.scene.Camera; 5 | import javafx.scene.Group; 6 | import javafx.scene.PerspectiveCamera; 7 | import javafx.scene.Scene; 8 | import javafx.scene.input.KeyEvent; 9 | import javafx.scene.paint.Color; 10 | import javafx.scene.shape.Box; 11 | import javafx.scene.transform.Rotate; 12 | import javafx.scene.transform.Transform; 13 | import javafx.stage.Stage; 14 | 15 | 16 | /** 17 | * @author afsal villan 18 | * @version 1.0 19 | * 20 | * http://www.genuinecoder.com 21 | */ 22 | public class Rotation3D extends Application { 23 | 24 | private static final int WIDTH = 1400; 25 | private static final int HEIGHT = 800; 26 | 27 | @Override 28 | public void start(Stage primaryStage) { 29 | Box box = new Box(100, 20, 50); 30 | 31 | SmartGroup group = new SmartGroup(); 32 | group.getChildren().add(box); 33 | 34 | Camera camera = new PerspectiveCamera(); 35 | Scene scene = new Scene(group, WIDTH, HEIGHT); 36 | scene.setFill(Color.SILVER); 37 | scene.setCamera(camera); 38 | 39 | group.translateXProperty().set(WIDTH / 2); 40 | group.translateYProperty().set(HEIGHT / 2); 41 | group.translateZProperty().set(-1200); 42 | 43 | primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> { 44 | switch (event.getCode()) { 45 | case W: 46 | group.translateZProperty().set(group.getTranslateZ() + 100); 47 | break; 48 | case S: 49 | group.translateZProperty().set(group.getTranslateZ() - 100); 50 | break; 51 | case Q: 52 | group.rotateByX(10); 53 | break; 54 | case E: 55 | group.rotateByX(-10); 56 | break; 57 | case NUMPAD6: 58 | group.rotateByY(10); 59 | break; 60 | case NUMPAD4: 61 | group.rotateByY(-10); 62 | break; 63 | } 64 | }); 65 | 66 | primaryStage.setTitle("Genuine Coder"); 67 | primaryStage.setScene(scene); 68 | primaryStage.show(); 69 | } 70 | 71 | 72 | public static void main(String[] args) { 73 | launch(args); 74 | } 75 | 76 | class SmartGroup extends Group { 77 | 78 | Rotate r; 79 | Transform t = new Rotate(); 80 | 81 | void rotateByX(int ang) { 82 | r = new Rotate(ang, Rotate.X_AXIS); 83 | t = t.createConcatenation(r); 84 | this.getTransforms().clear(); 85 | this.getTransforms().addAll(t); 86 | } 87 | 88 | void rotateByY(int ang) { 89 | r = new Rotate(ang, Rotate.Y_AXIS); 90 | t = t.createConcatenation(r); 91 | this.getTransforms().clear(); 92 | this.getTransforms().addAll(t); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt4/Rotation3DWithMouse.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt4; 2 | 3 | import javafx.application.Application; 4 | import javafx.beans.property.DoubleProperty; 5 | import javafx.beans.property.SimpleDoubleProperty; 6 | import javafx.scene.Camera; 7 | import javafx.scene.Group; 8 | import javafx.scene.PerspectiveCamera; 9 | import javafx.scene.Scene; 10 | import javafx.scene.input.KeyEvent; 11 | import javafx.scene.paint.Color; 12 | import javafx.scene.shape.Box; 13 | import javafx.scene.transform.Rotate; 14 | import javafx.scene.transform.Transform; 15 | import javafx.stage.Stage; 16 | 17 | /** 18 | * @author afsal villan 19 | * @version 1.0 20 | * 21 | * http://www.genuinecoder.com 22 | */ 23 | public class Rotation3DWithMouse extends Application { 24 | 25 | private static final int WIDTH = 1400; 26 | private static final int HEIGHT = 1000; 27 | 28 | private double anchorX, anchorY; 29 | private double anchorAngleX = 0; 30 | private double anchorAngleY = 0; 31 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 32 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 33 | 34 | @Override 35 | public void start(Stage primaryStage) { 36 | Box box = new Box(100, 20, 50); 37 | 38 | SmartGroup group = new SmartGroup(); 39 | group.getChildren().add(box); 40 | 41 | Camera camera = new PerspectiveCamera(); 42 | Scene scene = new Scene(group, WIDTH, HEIGHT); 43 | scene.setFill(Color.SILVER); 44 | scene.setCamera(camera); 45 | 46 | group.translateXProperty().set(WIDTH / 2); 47 | group.translateYProperty().set(HEIGHT / 2); 48 | group.translateZProperty().set(-1500); 49 | 50 | initMouseControl(group, scene); 51 | 52 | primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> { 53 | switch (event.getCode()) { 54 | case W: 55 | group.translateZProperty().set(group.getTranslateZ() + 100); 56 | break; 57 | case S: 58 | group.translateZProperty().set(group.getTranslateZ() - 100); 59 | break; 60 | case Q: 61 | group.rotateByX(10); 62 | break; 63 | case E: 64 | group.rotateByX(-10); 65 | break; 66 | case NUMPAD6: 67 | group.rotateByY(10); 68 | break; 69 | case NUMPAD4: 70 | group.rotateByY(-10); 71 | break; 72 | } 73 | }); 74 | 75 | primaryStage.setTitle("Genuine Coder"); 76 | primaryStage.setScene(scene); 77 | primaryStage.show(); 78 | } 79 | 80 | private void initMouseControl(SmartGroup group, Scene scene) { 81 | Rotate xRotate; 82 | Rotate yRotate; 83 | group.getTransforms().addAll( 84 | xRotate = new Rotate(0, Rotate.X_AXIS), 85 | yRotate = new Rotate(0, Rotate.Y_AXIS) 86 | ); 87 | xRotate.angleProperty().bind(angleX); 88 | yRotate.angleProperty().bind(angleY); 89 | 90 | scene.setOnMousePressed(event -> { 91 | anchorX = event.getSceneX(); 92 | anchorY = event.getSceneY(); 93 | anchorAngleX = angleX.get(); 94 | anchorAngleY = angleY.get(); 95 | }); 96 | 97 | scene.setOnMouseDragged(event -> { 98 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 99 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 100 | }); 101 | } 102 | 103 | public static void main(String[] args) { 104 | launch(args); 105 | } 106 | 107 | class SmartGroup extends Group { 108 | 109 | Rotate r; 110 | Transform t = new Rotate(); 111 | 112 | void rotateByX(int ang) { 113 | r = new Rotate(ang, Rotate.X_AXIS); 114 | t = t.createConcatenation(r); 115 | this.getTransforms().clear(); 116 | this.getTransforms().addAll(t); 117 | } 118 | 119 | void rotateByY(int ang) { 120 | r = new Rotate(ang, Rotate.Y_AXIS); 121 | t = t.createConcatenation(r); 122 | this.getTransforms().clear(); 123 | this.getTransforms().addAll(t); 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt5/MoreMouseControl.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt5; 2 | 3 | import javafx.application.Application; 4 | import javafx.beans.property.DoubleProperty; 5 | import javafx.beans.property.SimpleDoubleProperty; 6 | import javafx.scene.Camera; 7 | import javafx.scene.Group; 8 | import javafx.scene.PerspectiveCamera; 9 | import javafx.scene.Scene; 10 | import javafx.scene.input.KeyEvent; 11 | import javafx.scene.input.ScrollEvent; 12 | import javafx.scene.paint.Color; 13 | import javafx.scene.shape.Box; 14 | import javafx.scene.transform.Rotate; 15 | import javafx.scene.transform.Transform; 16 | import javafx.stage.Stage; 17 | 18 | /** 19 | * @author afsal villan 20 | * @version 1.0 21 | * 22 | * http://www.genuinecoder.com 23 | */ 24 | public class MoreMouseControl extends Application { 25 | 26 | private static final float WIDTH = 1400; 27 | private static final float HEIGHT = 1000; 28 | 29 | private double anchorX, anchorY; 30 | private double anchorAngleX = 0; 31 | private double anchorAngleY = 0; 32 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 33 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 34 | 35 | @Override 36 | public void start(Stage primaryStage) { 37 | Box box = new Box(100, 20, 50); 38 | 39 | SmartGroup group = new SmartGroup(); 40 | group.getChildren().add(box); 41 | 42 | Camera camera = new PerspectiveCamera(); 43 | Scene scene = new Scene(group, WIDTH, HEIGHT); 44 | scene.setFill(Color.SILVER); 45 | scene.setCamera(camera); 46 | 47 | group.translateXProperty().set(WIDTH / 2); 48 | group.translateYProperty().set(HEIGHT / 2); 49 | group.translateZProperty().set(-1500); 50 | 51 | initMouseControl(group, scene, primaryStage); 52 | 53 | primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> { 54 | switch (event.getCode()) { 55 | case W: 56 | group.translateZProperty().set(group.getTranslateZ() + 100); 57 | break; 58 | case S: 59 | group.translateZProperty().set(group.getTranslateZ() - 100); 60 | break; 61 | case Q: 62 | group.rotateByX(10); 63 | break; 64 | case E: 65 | group.rotateByX(-10); 66 | break; 67 | case NUMPAD6: 68 | group.rotateByY(10); 69 | break; 70 | case NUMPAD4: 71 | group.rotateByY(-10); 72 | break; 73 | } 74 | }); 75 | 76 | primaryStage.setTitle("Genuine Coder"); 77 | primaryStage.setScene(scene); 78 | primaryStage.show(); 79 | } 80 | 81 | private void initMouseControl(SmartGroup group, Scene scene, Stage stage) { 82 | Rotate xRotate; 83 | Rotate yRotate; 84 | group.getTransforms().addAll( 85 | xRotate = new Rotate(0, Rotate.X_AXIS), 86 | yRotate = new Rotate(0, Rotate.Y_AXIS) 87 | ); 88 | xRotate.angleProperty().bind(angleX); 89 | yRotate.angleProperty().bind(angleY); 90 | 91 | scene.setOnMousePressed(event -> { 92 | anchorX = event.getSceneX(); 93 | anchorY = event.getSceneY(); 94 | anchorAngleX = angleX.get(); 95 | anchorAngleY = angleY.get(); 96 | }); 97 | 98 | scene.setOnMouseDragged(event -> { 99 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 100 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 101 | }); 102 | 103 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 104 | double delta = event.getDeltaY(); 105 | group.translateZProperty().set(group.getTranslateZ() + delta); 106 | }); 107 | } 108 | 109 | public static void main(String[] args) { 110 | launch(args); 111 | } 112 | 113 | class SmartGroup extends Group { 114 | Rotate r; 115 | Transform t = new Rotate(); 116 | 117 | void rotateByX(int ang) { 118 | r = new Rotate(ang, Rotate.X_AXIS); 119 | t = t.createConcatenation(r); 120 | this.getTransforms().clear(); 121 | this.getTransforms().addAll(t); 122 | } 123 | 124 | void rotateByY(int ang) { 125 | r = new Rotate(ang, Rotate.Y_AXIS); 126 | t = t.createConcatenation(r); 127 | this.getTransforms().clear(); 128 | this.getTransforms().addAll(t); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt6/Texture.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt6; 2 | 3 | import javafx.application.Application; 4 | import javafx.beans.property.DoubleProperty; 5 | import javafx.beans.property.SimpleDoubleProperty; 6 | import javafx.scene.Camera; 7 | import javafx.scene.Group; 8 | import javafx.scene.PerspectiveCamera; 9 | import javafx.scene.Scene; 10 | import javafx.scene.image.Image; 11 | import javafx.scene.input.KeyEvent; 12 | import javafx.scene.input.ScrollEvent; 13 | import javafx.scene.paint.Color; 14 | import javafx.scene.paint.PhongMaterial; 15 | import javafx.scene.shape.Box; 16 | import javafx.scene.transform.Rotate; 17 | import javafx.scene.transform.Transform; 18 | import javafx.stage.Stage; 19 | 20 | /** 21 | * @author afsal villan 22 | * @version 1.0 23 | * 24 | * http://www.genuinecoder.com 25 | */ 26 | public class Texture extends Application { 27 | 28 | private static final float WIDTH = 1400; 29 | private static final float HEIGHT = 1000; 30 | 31 | private double anchorX, anchorY; 32 | private double anchorAngleX = 0; 33 | private double anchorAngleY = 0; 34 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 35 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 36 | 37 | @Override 38 | public void start(Stage primaryStage) { 39 | Box box = prepareBox(); 40 | 41 | SmartGroup group = new SmartGroup(); 42 | group.getChildren().add(box); 43 | 44 | Camera camera = new PerspectiveCamera(); 45 | Scene scene = new Scene(group, WIDTH, HEIGHT); 46 | scene.setFill(Color.SILVER); 47 | scene.setCamera(camera); 48 | 49 | group.translateXProperty().set(WIDTH / 2); 50 | group.translateYProperty().set(HEIGHT / 2); 51 | group.translateZProperty().set(-1500); 52 | 53 | initMouseControl(group, scene, primaryStage); 54 | 55 | primaryStage.setTitle("Genuine Coder"); 56 | primaryStage.setScene(scene); 57 | primaryStage.show(); 58 | } 59 | 60 | private Box prepareBox() { 61 | PhongMaterial material = new PhongMaterial(); 62 | material.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/wood.jpg"))); 63 | Box box = new Box(100, 20, 50); 64 | box.setMaterial(material); 65 | return box; 66 | } 67 | 68 | private void initMouseControl(SmartGroup group, Scene scene, Stage stage) { 69 | Rotate xRotate; 70 | Rotate yRotate; 71 | group.getTransforms().addAll( 72 | xRotate = new Rotate(0, Rotate.X_AXIS), 73 | yRotate = new Rotate(0, Rotate.Y_AXIS) 74 | ); 75 | xRotate.angleProperty().bind(angleX); 76 | yRotate.angleProperty().bind(angleY); 77 | 78 | scene.setOnMousePressed(event -> { 79 | anchorX = event.getSceneX(); 80 | anchorY = event.getSceneY(); 81 | anchorAngleX = angleX.get(); 82 | anchorAngleY = angleY.get(); 83 | }); 84 | 85 | scene.setOnMouseDragged(event -> { 86 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 87 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 88 | }); 89 | 90 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 91 | double delta = event.getDeltaY(); 92 | group.translateZProperty().set(group.getTranslateZ() + delta); 93 | }); 94 | } 95 | 96 | public static void main(String[] args) { 97 | launch(args); 98 | } 99 | 100 | class SmartGroup extends Group { 101 | 102 | Rotate r; 103 | Transform t = new Rotate(); 104 | 105 | void rotateByX(int ang) { 106 | r = new Rotate(ang, Rotate.X_AXIS); 107 | t = t.createConcatenation(r); 108 | this.getTransforms().clear(); 109 | this.getTransforms().addAll(t); 110 | } 111 | 112 | void rotateByY(int ang) { 113 | r = new Rotate(ang, Rotate.Y_AXIS); 114 | t = t.createConcatenation(r); 115 | this.getTransforms().clear(); 116 | this.getTransforms().addAll(t); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt7/Reflection.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt7; 2 | 3 | import javafx.application.Application; 4 | import javafx.beans.property.DoubleProperty; 5 | import javafx.beans.property.SimpleDoubleProperty; 6 | import javafx.scene.Camera; 7 | import javafx.scene.Group; 8 | import javafx.scene.PerspectiveCamera; 9 | import javafx.scene.Scene; 10 | import javafx.scene.image.Image; 11 | import javafx.scene.input.KeyEvent; 12 | import javafx.scene.input.ScrollEvent; 13 | import javafx.scene.paint.Color; 14 | import javafx.scene.paint.PhongMaterial; 15 | import javafx.scene.shape.Box; 16 | import javafx.scene.transform.Rotate; 17 | import javafx.scene.transform.Transform; 18 | import javafx.stage.Stage; 19 | 20 | /** 21 | * @author afsal villan 22 | * @version 1.0 23 | * 24 | * http://www.genuinecoder.com 25 | */ 26 | public class Reflection extends Application { 27 | 28 | private static final float WIDTH = 1400; 29 | private static final float HEIGHT = 1000; 30 | 31 | private double anchorX, anchorY; 32 | private double anchorAngleX = 0; 33 | private double anchorAngleY = 0; 34 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 35 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 36 | 37 | @Override 38 | public void start(Stage primaryStage) { 39 | Box box = prepareBox(); 40 | 41 | SmartGroup group = new SmartGroup(); 42 | group.getChildren().add(box); 43 | 44 | Camera camera = new PerspectiveCamera(true); 45 | camera.setNearClip(1); 46 | camera.setFarClip(1000); 47 | camera.translateZProperty().set(-200); 48 | 49 | Scene scene = new Scene(group, WIDTH, HEIGHT); 50 | scene.setFill(Color.SILVER); 51 | scene.setCamera(camera); 52 | 53 | group.translateXProperty().set(0); 54 | group.translateYProperty().set(0); 55 | group.translateZProperty().set(0); 56 | 57 | initMouseControl(group, scene, primaryStage); 58 | 59 | primaryStage.setTitle("Genuine Coder"); 60 | primaryStage.setScene(scene); 61 | primaryStage.show(); 62 | } 63 | 64 | private Box prepareBox() { 65 | PhongMaterial material = new PhongMaterial(); 66 | material.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/wood.jpg"))); 67 | material.setSpecularMap(new Image(getClass().getResourceAsStream("/resources/spec.jpg"))); 68 | 69 | Box box = new Box(100, 20, 50); 70 | box.setMaterial(material); 71 | return box; 72 | } 73 | 74 | private void initMouseControl(SmartGroup group, Scene scene, Stage stage) { 75 | Rotate xRotate; 76 | Rotate yRotate; 77 | group.getTransforms().addAll( 78 | xRotate = new Rotate(0, Rotate.X_AXIS), 79 | yRotate = new Rotate(0, Rotate.Y_AXIS) 80 | ); 81 | xRotate.angleProperty().bind(angleX); 82 | yRotate.angleProperty().bind(angleY); 83 | 84 | scene.setOnMousePressed(event -> { 85 | anchorX = event.getSceneX(); 86 | anchorY = event.getSceneY(); 87 | anchorAngleX = angleX.get(); 88 | anchorAngleY = angleY.get(); 89 | }); 90 | 91 | scene.setOnMouseDragged(event -> { 92 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 93 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 94 | }); 95 | 96 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 97 | double delta = event.getDeltaY(); 98 | group.translateZProperty().set(group.getTranslateZ() + delta); 99 | }); 100 | } 101 | 102 | public static void main(String[] args) { 103 | launch(args); 104 | } 105 | 106 | class SmartGroup extends Group { 107 | 108 | Rotate r; 109 | Transform t = new Rotate(); 110 | 111 | void rotateByX(int ang) { 112 | r = new Rotate(ang, Rotate.X_AXIS); 113 | t = t.createConcatenation(r); 114 | this.getTransforms().clear(); 115 | this.getTransforms().addAll(t); 116 | } 117 | 118 | void rotateByY(int ang) { 119 | r = new Rotate(ang, Rotate.Y_AXIS); 120 | t = t.createConcatenation(r); 121 | this.getTransforms().clear(); 122 | this.getTransforms().addAll(t); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt8/Lighting.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt8; 2 | 3 | import javafx.application.Application; 4 | import javafx.beans.property.DoubleProperty; 5 | import javafx.beans.property.SimpleDoubleProperty; 6 | import javafx.scene.AmbientLight; 7 | import javafx.scene.Camera; 8 | import javafx.scene.Group; 9 | import javafx.scene.LightBase; 10 | import javafx.scene.Node; 11 | import javafx.scene.PerspectiveCamera; 12 | import javafx.scene.PointLight; 13 | import javafx.scene.Scene; 14 | import javafx.scene.image.Image; 15 | import javafx.scene.input.KeyEvent; 16 | import javafx.scene.input.ScrollEvent; 17 | import javafx.scene.paint.Color; 18 | import javafx.scene.paint.PhongMaterial; 19 | import javafx.scene.shape.Box; 20 | import javafx.scene.shape.Sphere; 21 | import javafx.scene.transform.Rotate; 22 | import javafx.scene.transform.Transform; 23 | import javafx.scene.transform.Translate; 24 | import javafx.stage.Stage; 25 | 26 | /** 27 | * @author afsal villan 28 | * @version 1.0 29 | * 30 | * http://www.genuinecoder.com 31 | */ 32 | public class Lighting extends Application { 33 | 34 | private static final float WIDTH = 1400; 35 | private static final float HEIGHT = 1000; 36 | 37 | private double anchorX, anchorY; 38 | private double anchorAngleX = 0; 39 | private double anchorAngleY = 0; 40 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 41 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 42 | 43 | @Override 44 | public void start(Stage primaryStage) throws Exception { 45 | Box box = prepareBox(); 46 | 47 | SmartGroup group = new SmartGroup(); 48 | group.getChildren().add(box); 49 | group.getChildren().addAll(prepareLightSource()); 50 | 51 | //1. Ambient Light 52 | //2. Point Light 53 | 54 | Camera camera = new PerspectiveCamera(true); 55 | camera.setNearClip(1); 56 | camera.setFarClip(1000); 57 | camera.translateZProperty().set(-200); 58 | 59 | Scene scene = new Scene(group, WIDTH, HEIGHT); 60 | scene.setFill(Color.SILVER); 61 | scene.setCamera(camera); 62 | 63 | group.translateXProperty().set(0); 64 | group.translateYProperty().set(0); 65 | group.translateZProperty().set(0); 66 | 67 | initMouseControl(group, scene, primaryStage); 68 | 69 | primaryStage.setTitle("Genuine Coder"); 70 | primaryStage.setScene(scene); 71 | primaryStage.show(); 72 | } 73 | 74 | private Node[] prepareLightSource() { 75 | PointLight pointLight = new PointLight(); 76 | pointLight.setColor(Color.RED); 77 | pointLight.getTransforms().add(new Translate(0,-50,100)); 78 | 79 | Sphere sphere = new Sphere(2); 80 | sphere.getTransforms().setAll(pointLight.getTransforms()); 81 | return new Node[]{pointLight, sphere}; 82 | } 83 | 84 | private Box prepareBox() { 85 | PhongMaterial material = new PhongMaterial(); 86 | material.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/wood.jpg"))); 87 | 88 | Box box = new Box(100, 20, 50); 89 | box.setMaterial(material); 90 | return box; 91 | } 92 | 93 | private void initMouseControl(SmartGroup group, Scene scene, Stage stage) { 94 | Rotate xRotate; 95 | Rotate yRotate; 96 | group.getTransforms().addAll( 97 | xRotate = new Rotate(0, Rotate.X_AXIS), 98 | yRotate = new Rotate(0, Rotate.Y_AXIS) 99 | ); 100 | xRotate.angleProperty().bind(angleX); 101 | yRotate.angleProperty().bind(angleY); 102 | 103 | scene.setOnMousePressed(event -> { 104 | anchorX = event.getSceneX(); 105 | anchorY = event.getSceneY(); 106 | anchorAngleX = angleX.get(); 107 | anchorAngleY = angleY.get(); 108 | }); 109 | 110 | scene.setOnMouseDragged(event -> { 111 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 112 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 113 | }); 114 | 115 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 116 | double delta = event.getDeltaY(); 117 | group.translateZProperty().set(group.getTranslateZ() + delta); 118 | }); 119 | } 120 | 121 | public static void main(String[] args) { 122 | launch(args); 123 | } 124 | 125 | class SmartGroup extends Group { 126 | 127 | Rotate r; 128 | Transform t = new Rotate(); 129 | 130 | void rotateByX(int ang) { 131 | r = new Rotate(ang, Rotate.X_AXIS); 132 | t = t.createConcatenation(r); 133 | this.getTransforms().clear(); 134 | this.getTransforms().addAll(t); 135 | } 136 | 137 | void rotateByY(int ang) { 138 | r = new Rotate(ang, Rotate.Y_AXIS); 139 | t = t.createConcatenation(r); 140 | this.getTransforms().clear(); 141 | this.getTransforms().addAll(t); 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/gc/tutorial/chapt9/MovingLights.java: -------------------------------------------------------------------------------- 1 | package gc.tutorial.chapt9; 2 | 3 | import javafx.animation.AnimationTimer; 4 | import javafx.animation.RotateTransition; 5 | import javafx.application.Application; 6 | import javafx.beans.property.DoubleProperty; 7 | import javafx.beans.property.SimpleDoubleProperty; 8 | import javafx.scene.AmbientLight; 9 | import javafx.scene.Camera; 10 | import javafx.scene.Group; 11 | import javafx.scene.Node; 12 | import javafx.scene.PerspectiveCamera; 13 | import javafx.scene.PointLight; 14 | import javafx.scene.Scene; 15 | import javafx.scene.image.Image; 16 | import javafx.scene.input.KeyEvent; 17 | import javafx.scene.input.ScrollEvent; 18 | import javafx.scene.paint.Color; 19 | import javafx.scene.paint.PhongMaterial; 20 | import javafx.scene.shape.Box; 21 | import javafx.scene.shape.Sphere; 22 | import javafx.scene.transform.Rotate; 23 | import javafx.scene.transform.Transform; 24 | import javafx.scene.transform.Translate; 25 | import javafx.stage.Stage; 26 | import javafx.util.Duration; 27 | 28 | /** 29 | * @author afsal villan 30 | * @version 1.0 31 | * 32 | * http://www.genuinecoder.com 33 | */ 34 | public class MovingLights extends Application { 35 | 36 | private static final float WIDTH = 1400; 37 | private static final float HEIGHT = 1000; 38 | 39 | private double anchorX, anchorY; 40 | private double anchorAngleX = 0; 41 | private double anchorAngleY = 0; 42 | private final DoubleProperty angleX = new SimpleDoubleProperty(0); 43 | private final DoubleProperty angleY = new SimpleDoubleProperty(0); 44 | 45 | @Override 46 | public void start(Stage primaryStage) { 47 | Box box = prepareBox(); 48 | 49 | SmartGroup group = new SmartGroup(); 50 | group.getChildren().add(box); 51 | group.getChildren().addAll(prepareLightSource()); 52 | 53 | Camera camera = new PerspectiveCamera(true); 54 | camera.setNearClip(1); 55 | camera.setFarClip(1000); 56 | camera.translateZProperty().set(-200); 57 | 58 | Scene scene = new Scene(group, WIDTH, HEIGHT); 59 | scene.setFill(Color.SILVER); 60 | scene.setCamera(camera); 61 | 62 | group.translateXProperty().set(0); 63 | group.translateYProperty().set(0); 64 | group.translateZProperty().set(0); 65 | 66 | initMouseControl(group, scene, primaryStage); 67 | 68 | primaryStage.setTitle("Genuine Coder"); 69 | primaryStage.setScene(scene); 70 | primaryStage.show(); 71 | 72 | AnimationTimer timer = new AnimationTimer() { 73 | @Override 74 | public void handle(long now) { 75 | pointLight.setRotate(pointLight.getRotate() + 1); 76 | } 77 | }; 78 | timer.start(); 79 | } 80 | 81 | private final PointLight pointLight = new PointLight(); 82 | 83 | private Node[] prepareLightSource() { 84 | pointLight.setColor(Color.RED); 85 | pointLight.getTransforms().add(new Translate(0, -50, 100)); 86 | pointLight.setRotationAxis(Rotate.X_AXIS); 87 | 88 | Sphere sphere = new Sphere(2); 89 | sphere.getTransforms().setAll(pointLight.getTransforms()); 90 | sphere.rotateProperty().bind(pointLight.rotateProperty()); 91 | sphere.rotationAxisProperty().bind(pointLight.rotationAxisProperty()); 92 | 93 | return new Node[]{pointLight, sphere}; 94 | } 95 | 96 | private Box prepareBox() { 97 | PhongMaterial material = new PhongMaterial(); 98 | material.setDiffuseMap(new Image(getClass().getResourceAsStream("/resources/wood.jpg"))); 99 | 100 | Box box = new Box(100, 20, 50); 101 | box.setMaterial(material); 102 | return box; 103 | } 104 | 105 | private void initMouseControl(SmartGroup group, Scene scene, Stage stage) { 106 | Rotate xRotate; 107 | Rotate yRotate; 108 | group.getTransforms().addAll( 109 | xRotate = new Rotate(0, Rotate.X_AXIS), 110 | yRotate = new Rotate(0, Rotate.Y_AXIS) 111 | ); 112 | xRotate.angleProperty().bind(angleX); 113 | yRotate.angleProperty().bind(angleY); 114 | 115 | scene.setOnMousePressed(event -> { 116 | anchorX = event.getSceneX(); 117 | anchorY = event.getSceneY(); 118 | anchorAngleX = angleX.get(); 119 | anchorAngleY = angleY.get(); 120 | }); 121 | 122 | scene.setOnMouseDragged(event -> { 123 | angleX.set(anchorAngleX - (anchorY - event.getSceneY())); 124 | angleY.set(anchorAngleY + anchorX - event.getSceneX()); 125 | }); 126 | 127 | stage.addEventHandler(ScrollEvent.SCROLL, event -> { 128 | double delta = event.getDeltaY(); 129 | group.translateZProperty().set(group.getTranslateZ() + delta); 130 | }); 131 | } 132 | 133 | public static void main(String[] args) { 134 | launch(args); 135 | } 136 | 137 | class SmartGroup extends Group { 138 | 139 | Rotate r; 140 | Transform t = new Rotate(); 141 | 142 | void rotateByX(int ang) { 143 | r = new Rotate(ang, Rotate.X_AXIS); 144 | t = t.createConcatenation(r); 145 | this.getTransforms().clear(); 146 | this.getTransforms().addAll(t); 147 | } 148 | 149 | void rotateByY(int ang) { 150 | r = new Rotate(ang, Rotate.Y_AXIS); 151 | t = t.createConcatenation(r); 152 | this.getTransforms().clear(); 153 | this.getTransforms().addAll(t); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/resources/earth/earth-d.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afsalashyana/JavaFX-3D/8d94dff87e027136fa487491741c2eb1de44e301/src/resources/earth/earth-d.jpg -------------------------------------------------------------------------------- /src/resources/earth/earth-l.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afsalashyana/JavaFX-3D/8d94dff87e027136fa487491741c2eb1de44e301/src/resources/earth/earth-l.jpg -------------------------------------------------------------------------------- /src/resources/earth/earth-n.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afsalashyana/JavaFX-3D/8d94dff87e027136fa487491741c2eb1de44e301/src/resources/earth/earth-n.jpg -------------------------------------------------------------------------------- /src/resources/earth/earth-s.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afsalashyana/JavaFX-3D/8d94dff87e027136fa487491741c2eb1de44e301/src/resources/earth/earth-s.jpg -------------------------------------------------------------------------------- /src/resources/galaxy/galaxy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afsalashyana/JavaFX-3D/8d94dff87e027136fa487491741c2eb1de44e301/src/resources/galaxy/galaxy.jpg -------------------------------------------------------------------------------- /src/resources/illuminati2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afsalashyana/JavaFX-3D/8d94dff87e027136fa487491741c2eb1de44e301/src/resources/illuminati2.jpg -------------------------------------------------------------------------------- /src/resources/spec.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afsalashyana/JavaFX-3D/8d94dff87e027136fa487491741c2eb1de44e301/src/resources/spec.jpg -------------------------------------------------------------------------------- /src/resources/wood.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afsalashyana/JavaFX-3D/8d94dff87e027136fa487491741c2eb1de44e301/src/resources/wood.jpg --------------------------------------------------------------------------------