diff options
Diffstat (limited to 'ardor3d-examples')
140 files changed, 18217 insertions, 1972 deletions
diff --git a/ardor3d-examples/.gitignore b/ardor3d-examples/.gitignore deleted file mode 100644 index 15ef5ce..0000000 --- a/ardor3d-examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/ardorSettings.properties diff --git a/ardor3d-examples/.settings/org.eclipse.jdt.core.prefs b/ardor3d-examples/.settings/org.eclipse.jdt.core.prefs index 16496e9..941c850 100644 --- a/ardor3d-examples/.settings/org.eclipse.jdt.core.prefs +++ b/ardor3d-examples/.settings/org.eclipse.jdt.core.prefs @@ -89,12 +89,9 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert diff --git a/ardor3d-examples/.settings/org.eclipse.jdt.ui.prefs b/ardor3d-examples/.settings/org.eclipse.jdt.ui.prefs index 2cb0f4c..9cac248 100644 --- a/ardor3d-examples/.settings/org.eclipse.jdt.ui.prefs +++ b/ardor3d-examples/.settings/org.eclipse.jdt.ui.prefs @@ -59,7 +59,7 @@ org.eclipse.jdt.ui.gettersetter.use.is=true org.eclipse.jdt.ui.javadoc=false org.eclipse.jdt.ui.keywordthis=false org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"/><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">/**\r\n * Copyright (c) 2008-2010 Ardor Labs, Inc.\r\n *\r\n * This file is part of Ardor3D.\r\n *\r\n * Ardor3D is free software\: you can redistribute it and/or modify it \r\n * under the terms of its license which may be found in the accompanying\r\n * LICENSE file or at <http\://www.ardor3d.com/LICENSE>.\r\n */\r\n\r\n${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates> +org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"/><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">/**\r\n * Copyright (c) 2008-2014 Ardor Labs, Inc.\r\n *\r\n * This file is part of Ardor3D.\r\n *\r\n * Ardor3D is free software\: you can redistribute it and/or modify it \r\n * under the terms of its license which may be found in the accompanying\r\n * LICENSE file or at <http\://www.ardor3d.com/LICENSE>.\r\n */\r\n\r\n${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates> sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true @@ -82,7 +82,7 @@ sp_cleanup.make_private_fields_final=true sp_cleanup.make_type_abstract_if_missing_method=false sp_cleanup.make_variable_declarations_final=true sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.never_use_parentheses_in_expressions=false sp_cleanup.on_save_use_additional_actions=true sp_cleanup.organize_imports=true sp_cleanup.qualify_static_field_accesses_with_declaring_class=false diff --git a/ardor3d-examples/assembly.xml b/ardor3d-examples/assembly.xml index be12458..ce3091c 100644 --- a/ardor3d-examples/assembly.xml +++ b/ardor3d-examples/assembly.xml @@ -39,7 +39,6 @@ <useProjectArtifact>false</useProjectArtifact> <useStrictFiltering>true</useStrictFiltering> <excludes> - <exclude>*:lwjgl*:*:natives-*</exclude> <exclude>*:jinput*:*:natives-*</exclude> </excludes> <outputDirectory>lib</outputDirectory> diff --git a/ardor3d-examples/build.gradle b/ardor3d-examples/build.gradle index 503b787..f07954b 100644 --- a/ardor3d-examples/build.gradle +++ b/ardor3d-examples/build.gradle @@ -1,11 +1,12 @@ description = 'Ardor 3D Examples' dependencies { - compile project(':ardor3d-lwjgl') - compile group: 'org.lwjgl.lwjgl', name: 'lwjgl', version:'2.9.3' compile project(':ardor3d-awt') compile project(':ardor3d-swt') + compile project(':ardor3d-jinput') compile project(':ardor3d-jogl') + compile project(':ardor3d-jogl-awt') + compile project(':ardor3d-jogl-swt') compile project(':ardor3d-effects') compile project(':ardor3d-extras') compile project(':ardor3d-collada') diff --git a/ardor3d-examples/pom.xml b/ardor3d-examples/pom.xml index 07cebd2..7350176 100644 --- a/ardor3d-examples/pom.xml +++ b/ardor3d-examples/pom.xml @@ -109,27 +109,32 @@ <dependencies> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>ardor3d-lwjgl</artifactId> + <artifactId>ardor3d-awt</artifactId> <version>${project.version}</version> </dependency> - <!-- because we use org.lwjgl.LWJGLException in LwjglSwtExample --> <dependency> - <groupId>org.lwjgl.lwjgl</groupId> - <artifactId>lwjgl</artifactId> + <groupId>${project.groupId}</groupId> + <artifactId>ardor3d-swt</artifactId> + <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>ardor3d-awt</artifactId> + <artifactId>ardor3d-jinput</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>ardor3d-swt</artifactId> + <artifactId>ardor3d-jogl</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ardor3d-jogl-awt</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>ardor3d-jogl</artifactId> + <artifactId>ardor3d-jogl-swt</artifactId> <version>${project.version}</version> </dependency> <dependency> diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/ExampleBase.java b/ardor3d-examples/src/main/java/com/ardor3d/example/ExampleBase.java index 4f24172..1ac5650 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/ExampleBase.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/ExampleBase.java @@ -1,9 +1,9 @@ /** - * Copyright (c) 2008-2017 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * - * Ardor3D is free software: you can redistribute it and/or modify it + * Ardor3D is free software: you can redistribute it and/or modify it * under the terms of its license which may be found in the accompanying * LICENSE file or at <http://www.ardor3d.com/LICENSE>. */ @@ -28,11 +28,9 @@ import com.ardor3d.framework.Scene; import com.ardor3d.framework.Updater; import com.ardor3d.framework.jogl.JoglCanvasRenderer; import com.ardor3d.framework.jogl.JoglNewtWindow; -import com.ardor3d.framework.lwjgl.LwjglCanvas; -import com.ardor3d.framework.lwjgl.LwjglCanvasRenderer; import com.ardor3d.image.TextureStoreFormat; -import com.ardor3d.image.util.awt.AWTImageLoader; import com.ardor3d.image.util.awt.ScreenShotImageExporter; +import com.ardor3d.image.util.jogl.JoglImageLoader; import com.ardor3d.input.GrabbedState; import com.ardor3d.input.Key; import com.ardor3d.input.MouseButton; @@ -53,10 +51,6 @@ import com.ardor3d.input.logical.MouseButtonPressedCondition; import com.ardor3d.input.logical.MouseButtonReleasedCondition; import com.ardor3d.input.logical.TriggerAction; import com.ardor3d.input.logical.TwoInputStates; -import com.ardor3d.input.lwjgl.LwjglControllerWrapper; -import com.ardor3d.input.lwjgl.LwjglKeyboardWrapper; -import com.ardor3d.input.lwjgl.LwjglMouseManager; -import com.ardor3d.input.lwjgl.LwjglMouseWrapper; import com.ardor3d.intersection.PickData; import com.ardor3d.intersection.PickResults; import com.ardor3d.intersection.PickingUtil; @@ -71,12 +65,10 @@ import com.ardor3d.renderer.ContextManager; import com.ardor3d.renderer.Renderer; import com.ardor3d.renderer.TextureRendererFactory; import com.ardor3d.renderer.jogl.JoglTextureRendererProvider; -import com.ardor3d.renderer.lwjgl.LwjglTextureRendererProvider; import com.ardor3d.renderer.queue.RenderBucketType; import com.ardor3d.renderer.state.LightState; import com.ardor3d.renderer.state.WireframeState; import com.ardor3d.renderer.state.ZBufferState; -import com.ardor3d.scene.state.lwjgl.util.SharedLibraryLoader; import com.ardor3d.scenegraph.Node; import com.ardor3d.scenegraph.event.DirtyType; import com.ardor3d.util.Constants; @@ -92,6 +84,8 @@ import com.ardor3d.util.screen.ScreenExporter; import com.ardor3d.util.stat.StatCollector; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; public abstract class ExampleBase implements Runnable, Updater, Scene { private static final Logger logger = Logger.getLogger(ExampleBase.class.getName()); @@ -140,25 +134,48 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { protected static int _minAlphaBits = -1; protected static int _minStencilBits = -1; + @Override public void run() { try { + if (_canvas instanceof JoglNewtWindow) { + ((JoglNewtWindow) _canvas).addWindowListener(new WindowAdapter() { + @Override + public void windowDestroyNotify(final WindowEvent e) { + final CanvasRenderer cr = _canvas.getCanvasRenderer(); + // grab the graphics context so cleanup will work out. + cr.makeCurrentContext(); + ContextGarbageCollector.doFinalCleanup(cr.getRenderer()); + cr.releaseCurrentContext(); + } + }); + } + // else if (_canvas instanceof JoglAwtWindow) { + // ((JoglAwtWindow) _canvas).addWindowListener(new java.awt.event.WindowAdapter() { + // @Override + // public void windowClosing(final java.awt.event.WindowEvent e) { + // final CanvasRenderer cr = _canvas.getCanvasRenderer(); + // // grab the graphics context so cleanup will work out. + // cr.makeCurrentContext(); + // ContextGarbageCollector.doFinalCleanup(cr.getRenderer()); + // cr.releaseCurrentContext(); + // } + // }); + // } + _frameHandler.init(); while (!_exit) { _frameHandler.updateFrame(); Thread.yield(); } - // grab the graphics context so cleanup will work out. - final CanvasRenderer cr = _canvas.getCanvasRenderer(); - cr.makeCurrentContext(); - quit(cr.getRenderer()); - cr.releaseCurrentContext(); - if (QUIT_VM_ON_EXIT) { - System.exit(0); - } } catch (final Throwable t) { System.err.println("Throwable caught in MainThread - exiting"); t.printStackTrace(System.err); + } finally { + // quit even though the cleanup has just failed + if (QUIT_VM_ON_EXIT) { + System.exit(0); + } } } @@ -166,6 +183,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { _exit = true; } + @Override @MainThread public void init() { final ContextCapabilities caps = ContextManager.getCurrentContext().getCapabilities(); @@ -176,7 +194,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { registerInputTriggers(); - AWTImageLoader.registerLoader(); + JoglImageLoader.registerLoader(); try { SimpleResourceLocator srl = new SimpleResourceLocator(ResourceLocatorTool.getClassPathResource( @@ -224,6 +242,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { protected abstract void initExample(); + @Override @MainThread public void update(final ReadOnlyTimer timer) { if (_canvas.isClosing()) { @@ -259,6 +278,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { // does nothing } + @Override @MainThread public boolean renderUnto(final Renderer renderer) { // Execute renderQueue item @@ -306,6 +326,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { } } + @Override public PickResults doPick(final Ray3 pickRay) { final PrimitivePickResults pickResults = new PrimitivePickResults(); pickResults.setCheckDistance(true); @@ -359,26 +380,13 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { example._settings = settings; // get our framework - if (prefs.getRenderer().startsWith("LWJGL")) { - try { - SharedLibraryLoader.load(true); - } catch (Exception e) {e.printStackTrace();} - - final LwjglCanvasRenderer canvasRenderer = new LwjglCanvasRenderer(example); - example._canvas = new LwjglCanvas(settings, canvasRenderer); - example._physicalLayer = new PhysicalLayer(new LwjglKeyboardWrapper(), new LwjglMouseWrapper(), - new LwjglControllerWrapper(), (LwjglCanvas) example._canvas); - example._mouseManager = new LwjglMouseManager(); - TextureRendererFactory.INSTANCE.setProvider(new LwjglTextureRendererProvider()); - } else if (prefs.getRenderer().startsWith("JOGL")) { - final JoglCanvasRenderer canvasRenderer = new JoglCanvasRenderer(example); - example._canvas = new JoglNewtWindow(canvasRenderer, settings); - final JoglNewtWindow canvas = (JoglNewtWindow) example._canvas; - example._mouseManager = new JoglNewtMouseManager(canvas); - example._physicalLayer = new PhysicalLayer(new JoglNewtKeyboardWrapper(canvas), new JoglNewtMouseWrapper( - canvas, example._mouseManager), DummyControllerWrapper.INSTANCE, new JoglNewtFocusWrapper(canvas)); - TextureRendererFactory.INSTANCE.setProvider(new JoglTextureRendererProvider()); - } + final JoglCanvasRenderer canvasRenderer = new JoglCanvasRenderer(example); + example._canvas = new JoglNewtWindow(canvasRenderer, settings); + final JoglNewtWindow canvas = (JoglNewtWindow) example._canvas; + example._mouseManager = new JoglNewtMouseManager(canvas); + example._physicalLayer = new PhysicalLayer(new JoglNewtKeyboardWrapper(canvas), new JoglNewtMouseWrapper( + canvas, example._mouseManager), DummyControllerWrapper.INSTANCE, new JoglNewtFocusWrapper(canvas)); + TextureRendererFactory.INSTANCE.setProvider(new JoglTextureRendererProvider()); example._logicalLayer.registerInput(example._canvas, example._physicalLayer); @@ -409,13 +417,14 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { } final URL dialogImageRef = dialogImage; - final AtomicReference<PropertiesDialog> dialogRef = new AtomicReference<PropertiesDialog>(); - final Stack<Runnable> mainThreadTasks = new Stack<Runnable>(); + final AtomicReference<PropertiesDialog> dialogRef = new AtomicReference<>(); + final Stack<Runnable> mainThreadTasks = new Stack<>(); try { if (EventQueue.isDispatchThread()) { dialogRef.set(new PropertiesDialog(settings, dialogImageRef, mainThreadTasks)); } else { EventQueue.invokeLater(new Runnable() { + @Override public void run() { dialogRef.set(new PropertiesDialog(settings, dialogImageRef, mainThreadTasks)); } @@ -460,6 +469,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonClickedCondition(MouseButton.RIGHT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { final Vector2 pos = Vector2.fetchTempInstance().set( @@ -473,12 +483,14 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { }, "pickTrigger")); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ESCAPE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { exit(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.L), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { _lightState.setEnabled(!_lightState.isEnabled()); // Either an update or a markDirty is needed here since we did not touch the affected spatial directly. @@ -487,12 +499,14 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F4), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { _showDepth = !_showDepth; } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.T), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { _wireframeState.setEnabled(!_wireframeState.isEnabled()); // Either an update or a markDirty is needed here since we did not touch the affected spatial directly. @@ -501,24 +515,28 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.B), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { _showBounds = !_showBounds; } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.C), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { System.out.println("Camera: " + _canvas.getCanvasRenderer().getCamera()); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.N), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { _showNormals = !_showNormals; } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F1), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { _doShot = true; } @@ -528,6 +546,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { MouseButton.LEFT), new MouseButtonClickedCondition(MouseButton.RIGHT)); _logicalLayer.registerTrigger(new InputTrigger(clickLeftOrRight, new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { System.err.println("clicked: " + inputStates.getCurrent().getMouseState().getClickCounts()); } @@ -535,6 +554,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonPressedCondition(MouseButton.LEFT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { if (_mouseManager.isSetGrabbedSupported()) { _mouseManager.setGrabbed(GrabbedState.GRABBED); @@ -543,6 +563,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { })); _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonReleasedCondition(MouseButton.LEFT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { if (_mouseManager.isSetGrabbedSupported()) { _mouseManager.setGrabbed(GrabbedState.NOT_GRABBED); @@ -551,6 +572,7 @@ public abstract class ExampleBase implements Runnable, Updater, Scene { })); _logicalLayer.registerTrigger(new InputTrigger(new AnyKeyCondition(), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { System.out.println("Key character pressed: " + inputState.getCurrent().getKeyboardState().getKeyEvent().getKeyChar()); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/ExampleRunner.java b/ardor3d-examples/src/main/java/com/ardor3d/example/ExampleRunner.java index d3708be..a3fd849 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/ExampleRunner.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/ExampleRunner.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -29,6 +29,7 @@ import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; @@ -84,7 +85,6 @@ import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import com.ardor3d.util.resource.ResourceLocatorTool; -import com.google.common.collect.Lists; /** * starter for Ardor3D examples @@ -114,6 +114,7 @@ public class ExampleRunner extends JFrame { "com/ardor3d/example/media/images/ardor3d_white_256.jpg") + "\"></p></body></html>"; private static Comparator<Class<?>> classComparator = new Comparator<Class<?>>() { + @Override public int compare(final Class<?> o1, final Class<?> o2) { return o1.getCanonicalName().compareTo(o2.getCanonicalName()); } @@ -130,14 +131,17 @@ public class ExampleRunner extends JFrame { tfPattern = new ErasableTextField(10); tfPattern.getDocument().addDocumentListener(new DocumentListener() { + @Override public void removeUpdate(final DocumentEvent e) { search(); } + @Override public void insertUpdate(final DocumentEvent e) { search(); } + @Override public void changedUpdate(final DocumentEvent e) { search(); } @@ -152,6 +156,7 @@ public class ExampleRunner extends JFrame { putValue(Action.SHORT_DESCRIPTION, "Expand all branches"); } + @Override public void actionPerformed(final ActionEvent e) { if (((JToggleButton) e.getSource()).isSelected()) { for (int row = 0; row < tree.getRowCount(); row++) { @@ -192,6 +197,7 @@ public class ExampleRunner extends JFrame { putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control R")); } + @Override public void actionPerformed(final ActionEvent e) { runSelected(); } @@ -209,6 +215,7 @@ public class ExampleRunner extends JFrame { putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control B")); } + @Override public void actionPerformed(final ActionEvent e) { browseSelected(); } @@ -224,6 +231,7 @@ public class ExampleRunner extends JFrame { putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control P")); } + @Override public void actionPerformed(final ActionEvent e) { navigateInMatches(-1); } @@ -239,6 +247,7 @@ public class ExampleRunner extends JFrame { putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control N")); } + @Override public void actionPerformed(final ActionEvent e) { navigateInMatches(1); } @@ -254,6 +263,7 @@ public class ExampleRunner extends JFrame { putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control F")); } + @Override public void actionPerformed(final ActionEvent e) { tree.setSelectionRow(0); navigateInMatches(1); @@ -306,6 +316,7 @@ public class ExampleRunner extends JFrame { tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + @Override public void valueChanged(final TreeSelectionEvent e) { updateDescription(); updateActionStatus(); @@ -438,7 +449,7 @@ public class ExampleRunner extends JFrame { final Class<?> clazz = (Class<?>) selected; final boolean isWindows = System.getProperty("os.name").contains("Windows"); - final List<String> args = Lists.newArrayList(); + final List<String> args = new ArrayList<>(); args.add(isWindows ? "javaw" : "java"); args.add("-Xmx" + maxHeapMemory + "M"); args.add("-cp"); @@ -498,28 +509,31 @@ public class ExampleRunner extends JFrame { class ClassTreeModel implements TreeModel, SearchFilter { private final EventListenerList listeners = new EventListenerList(); - private final LinkedHashMap<Package, Vector<Class<?>>> classes = new LinkedHashMap<Package, Vector<Class<?>>>(); + private final LinkedHashMap<Package, Vector<Class<?>>> classes = new LinkedHashMap<>(); // the next two maps are for caching the status for the search filter - private final HashMap<Class<?>, Boolean> classMatches = new HashMap<Class<?>, Boolean>(); - private final HashMap<Package, Boolean> packageMatches = new HashMap<Package, Boolean>(); + private final HashMap<Class<?>, Boolean> classMatches = new HashMap<>(); + private final HashMap<Package, Boolean> packageMatches = new HashMap<>(); private String root = "all examples"; private FileFilter classFileFilter; private int size; private int matchCount = 0; + @Override public void addTreeModelListener(final TreeModelListener l) { listeners.add(TreeModelListener.class, l); } + @Override public Object getChild(final Object parent, final int index) { if (root.equals(parent)) { - final Vector<Package> vec = new Vector<Package>(classes.keySet()); + final Vector<Package> vec = new Vector<>(classes.keySet()); return vec.get(index); } final Vector<Class<?>> cl = classes.get(parent); return cl == null ? null : cl.get(index); } + @Override public int getChildCount(final Object parent) { if (root.equals(parent)) { return classes.size(); @@ -528,15 +542,17 @@ public class ExampleRunner extends JFrame { return cl == null ? 0 : cl.size(); } + @Override public int getIndexOfChild(final Object parent, final Object child) { if (root.equals(parent)) { - final Vector<Package> vec = new Vector<Package>(classes.keySet()); + final Vector<Package> vec = new Vector<>(classes.keySet()); return vec.indexOf(child); } final Vector<Class<?>> cl = classes.get(parent); return cl == null ? 0 : cl.indexOf(child); } + @Override public Object getRoot() { return root; } @@ -550,7 +566,7 @@ public class ExampleRunner extends JFrame { classMatches.put(clazz, false); Vector<Class<?>> cl = classes.get(clazz.getPackage()); if (cl == null) { - cl = new Vector<Class<?>>(); + cl = new Vector<>(); classes.put(clazz.getPackage(), cl); } size++; @@ -558,6 +574,7 @@ public class ExampleRunner extends JFrame { Collections.sort(cl, classComparator); } + @Override public int updateMatches(final String pattern) { int numberMatches = 0; final String lcPattern = pattern.toLowerCase(); @@ -610,6 +627,7 @@ public class ExampleRunner extends JFrame { return numberMatches; } + @Override public boolean matches(final Object value) { if (value instanceof Class<?>) { return classMatches.get(value); @@ -619,14 +637,17 @@ public class ExampleRunner extends JFrame { return res == null ? false : res; } + @Override public boolean isLeaf(final Object node) { return node instanceof Class<?>; } + @Override public void removeTreeModelListener(final TreeModelListener l) { listeners.remove(TreeModelListener.class, l); } + @Override public void valueForPathChanged(final TreePath path, final Object newValue) { fireTreeNodeChanged(path); } @@ -641,6 +662,7 @@ public class ExampleRunner extends JFrame { /** * @see FileFilter */ + @Override public boolean accept(final File pathname) { return (pathname.isDirectory() && (pathname.getName().length() == 0 || pathname.getName() .charAt(0) != '.')) @@ -838,16 +860,17 @@ public class ExampleRunner extends JFrame { this.searchFilter = searchFilter; } + @Override public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean selected, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { if (value == null) { classNameLabel.setText("Null"); // Throw an exception? classNameLabel.setFont(defaultFont); } else { - if ((value != null) && (value instanceof Class<?>)) { + if (value instanceof Class<?>) { final Class<?> clazz = (Class<?>) value; classNameLabel.setText(clazz.getSimpleName()); - } else if ((value != null) && value instanceof Package) { + } else if (value instanceof Package) { String name = ((Package) value).getName(); if (name.startsWith(tree.getModel().getRoot().toString())) { name = name.substring(tree.getModel().getRoot().toString().length() + 1); @@ -969,6 +992,7 @@ public class ExampleRunner extends JFrame { putValue(Action.SMALL_ICON, getIcon("edit-clear-locationbar-rtl.png")); } + @Override public void actionPerformed(final ActionEvent e) { textField.setText(""); } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/GameThread.java b/ardor3d-examples/src/main/java/com/ardor3d/example/GameThread.java index 97bb1d7..357c164 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/GameThread.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/GameThread.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/PropertiesDialog.java b/ardor3d-examples/src/main/java/com/ardor3d/example/PropertiesDialog.java index 80f02df..a0c22b1 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/PropertiesDialog.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/PropertiesDialog.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -266,13 +266,15 @@ public final class PropertiesDialog extends JDialog { displayResCombo.addKeyListener(aListener); samplesCombo = setUpSamplesChooser(); samplesCombo.addKeyListener(aListener); - colorDepthCombo = new JComboBox<String>(); + colorDepthCombo = new JComboBox<>(); colorDepthCombo.addKeyListener(aListener); - displayFreqCombo = new JComboBox<String>(); + displayFreqCombo = new JComboBox<>(); + displayFreqCombo.addKeyListener(aListener); fullscreenBox = new JCheckBox("Fullscreen?"); fullscreenBox.setSelected(source.isFullscreen()); fullscreenBox.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent e) { updateResolutionChoices(); } @@ -295,6 +297,7 @@ public final class PropertiesDialog extends JDialog { // Set the button action listeners. Cancel disposes without saving, OK // saves. ok.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent e) { if (verifyAndSaveCurrentSelection()) { dispose(); @@ -303,6 +306,7 @@ public final class PropertiesDialog extends JDialog { }); cancel.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent e) { cancelled = true; dispose(); @@ -410,10 +414,11 @@ public final class PropertiesDialog extends JDialog { */ private JComboBox<String> setUpResolutionChooser() { final String[] res = getResolutions(modes); - final JComboBox<String> resolutionBox = new JComboBox<String>(res); + final JComboBox<String> resolutionBox = new JComboBox<>(res); resolutionBox.setSelectedItem(source.getWidth() + " x " + source.getHeight()); resolutionBox.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent e) { updateDisplayChoices(); } @@ -429,20 +434,20 @@ public final class PropertiesDialog extends JDialog { * @return the list of renderers. */ private JComboBox<String> setUpRendererChooser() { - final JComboBox<String> nameBox = new JComboBox<String>(new String[] { "LWJGL 2.9.3", "JOGL 2.0rc11" }); - final String old = source.getRenderer(); - if (old != null) { - if (old.startsWith("LWJGL")) { - nameBox.setSelectedIndex(0); - } else if (old.startsWith("JOGL")) { - nameBox.setSelectedIndex(1); - } - } + final JComboBox<String> nameBox = new JComboBox<>(new String[] { "JOGL 2" }); + // final String old = source.getRenderer(); + /* + * if (old != null) { if (old.startsWith("JOGL")) { + */ + nameBox.setSelectedIndex(0); + /* + * } } + */ return nameBox; } private JComboBox<String> setUpSamplesChooser() { - final JComboBox<String> nameBox = new JComboBox<String>(samples); + final JComboBox<String> nameBox = new JComboBox<>(samples); nameBox.setSelectedItem(source.getRenderer()); return nameBox; } @@ -468,11 +473,11 @@ public final class PropertiesDialog extends JDialog { // grab available depths final String[] depths = getDepths(resolution, modes); - colorDepthCombo.setModel(new DefaultComboBoxModel<String>(depths)); + colorDepthCombo.setModel(new DefaultComboBoxModel<>(depths)); colorDepthCombo.setSelectedItem(colorDepth); // grab available frequencies final String[] freqs = getFrequencies(resolution, modes); - displayFreqCombo.setModel(new DefaultComboBoxModel<String>(freqs)); + displayFreqCombo.setModel(new DefaultComboBoxModel<>(freqs)); // Try to reset freq displayFreqCombo.setSelectedItem(displayFreq); } @@ -484,12 +489,12 @@ public final class PropertiesDialog extends JDialog { */ private void updateResolutionChoices() { if (!fullscreenBox.isSelected()) { - displayResCombo.setModel(new DefaultComboBoxModel<String>(windowedResolutions)); - colorDepthCombo.setModel(new DefaultComboBoxModel<String>(new String[] { "24 bpp", "16 bpp" })); - displayFreqCombo.setModel(new DefaultComboBoxModel<String>(new String[] { "n/a" })); + displayResCombo.setModel(new DefaultComboBoxModel<>(windowedResolutions)); + colorDepthCombo.setModel(new DefaultComboBoxModel<>(new String[] { "24 bpp", "16 bpp" })); + displayFreqCombo.setModel(new DefaultComboBoxModel<>(new String[] { "n/a" })); displayFreqCombo.setEnabled(false); } else { - displayResCombo.setModel(new DefaultComboBoxModel<String>(getResolutions(modes))); + displayResCombo.setModel(new DefaultComboBoxModel<>(getResolutions(modes))); displayFreqCombo.setEnabled(true); updateDisplayChoices(); } @@ -522,7 +527,7 @@ public final class PropertiesDialog extends JDialog { * Returns every unique resolution from an array of <code>DisplayMode</code>s. */ private static String[] getResolutions(final DisplayMode[] modes) { - final List<String> resolutions = new ArrayList<String>(modes.length); + final List<String> resolutions = new ArrayList<>(modes.length); for (int i = 0; i < modes.length; i++) { final String res = modes[i].getWidth() + " x " + modes[i].getHeight(); if (!resolutions.contains(res)) { @@ -539,7 +544,8 @@ public final class PropertiesDialog extends JDialog { * Returns every possible bit depth for the given resolution. */ private static String[] getDepths(final String resolution, final DisplayMode[] modes) { - final Set<String> depths = new TreeSet<String>(new Comparator<String>() { + final Set<String> depths = new TreeSet<>(new Comparator<String>() { + @Override public int compare(final String o1, final String o2) { // reverse order return -o1.compareTo(o2); @@ -568,7 +574,7 @@ public final class PropertiesDialog extends JDialog { * Returns every possible refresh rate for the given resolution. */ private static String[] getFrequencies(final String resolution, final DisplayMode[] modes) { - final List<String> freqs = new ArrayList<String>(4); + final List<String> freqs = new ArrayList<>(4); for (int i = 0; i < modes.length; i++) { final String res = modes[i].getWidth() + " x " + modes[i].getHeight(); final String freq = modes[i].getRefreshRate() + " Hz"; @@ -590,6 +596,7 @@ public final class PropertiesDialog extends JDialog { /** * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ + @Override public int compare(final DisplayMode a, final DisplayMode b) { // Width if (a.getWidth() != b.getWidth()) { @@ -630,10 +637,9 @@ public final class PropertiesDialog extends JDialog { this.renderer = renderer; } + @Override public void run() { - if (renderer.startsWith("LWJGL")) { - // TODO: can we implement this? - } else if (renderer.startsWith("JOGL")) { + if (renderer.startsWith("JOGL")) { // TODO: can we implement this? } ready = true; @@ -657,6 +663,7 @@ public final class PropertiesDialog extends JDialog { ModesRetriever() {} + @Override public void run() { try { modes = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayModes(); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/PropertiesGameSettings.java b/ardor3d-examples/src/main/java/com/ardor3d/example/PropertiesGameSettings.java index c180576..996cc57 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/PropertiesGameSettings.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/PropertiesGameSettings.java @@ -1,9 +1,9 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * - * Ardor3D is free software: you can redistribute it and/or modify it + * Ardor3D is free software: you can redistribute it and/or modify it * under the terms of its license which may be found in the accompanying * LICENSE file or at <http://www.ardor3d.com/LICENSE>. */ @@ -12,7 +12,6 @@ package com.ardor3d.example; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -26,11 +25,11 @@ import com.ardor3d.util.resource.ResourceLocatorTool; /** * <code>PropertiesGameSettings</code> handles loading and saving a properties file that defines the display settings. A * property file is identified during creation of the object. The properties file should have the following format: - * + * * <PRE> * <CODE> * FREQ=60 - * RENDERER=LWJGL + * RENDERER=JOGL * WIDTH=1280 * HEIGHT=1024 * DEPTH=32 @@ -64,7 +63,7 @@ public class PropertiesGameSettings { /** * The default renderer flag, used if there is a problem with the properties file. */ - static String DEFAULT_RENDERER = "LWJGL"; + static String DEFAULT_RENDERER = "JOGL"; static boolean DEFAULT_VERTICAL_SYNC = true; static int DEFAULT_DEPTH_BITS = 8; @@ -106,7 +105,7 @@ public class PropertiesGameSettings { /** * Constructor creates the <code>PropertiesGameSettings</code> object for use. - * + * * @param personalFilename * the properties file to use, read from filesystem. Must not be null. * @param dfltsFilename @@ -138,7 +137,7 @@ public class PropertiesGameSettings { /** * <code>get</code> takes an arbitrary string as a key and returns any value associated with it, null if none. - * + * * @param key * the key to use for data retrieval. * @return the string associated with the key, null if none. @@ -154,7 +153,7 @@ public class PropertiesGameSettings { /** * If the properties file does not contain the setting or was not read properly, the default value is returned. - * + * * @throws InternalError * in all cases */ @@ -183,7 +182,7 @@ public class PropertiesGameSettings { /** * <code>getDepth</code> returns the depth as read from the properties file. If the properties file does not contain * depth or was not read properly, the default depth is returned. - * + * * @return the depth determined by the properties file, or the default. */ public int getDepth() { @@ -197,7 +196,7 @@ public class PropertiesGameSettings { /** * If the properties file does not contain the setting or was not read properly, the default value is returned. - * + * * @throws InternalError * in all cases */ @@ -218,7 +217,7 @@ public class PropertiesGameSettings { /** * If the properties file does not contain the setting or was not read properly, the default value is returned. - * + * * @throws InternalError * in all cases */ @@ -230,7 +229,7 @@ public class PropertiesGameSettings { /** * <code>getFrequency</code> returns the frequency of the monitor as read from the properties file. If the * properties file does not contain frequency or was not read properly the default frequency is returned. - * + * * @return the frequency determined by the properties file, or the default. */ public int getFrequency() { @@ -244,7 +243,7 @@ public class PropertiesGameSettings { /** * Legacy method. - * + * * @deprecated Use method isFullscreen instead. * @see #isFullscreen() */ @@ -256,7 +255,7 @@ public class PropertiesGameSettings { /** * <code>getHeight</code> returns the height as read from the properties file. If the properties file does not * contain height or was not read properly, the default height is returned. - * + * * @return the height determined by the properties file, or the default. */ public int getHeight() { @@ -284,9 +283,9 @@ public class PropertiesGameSettings { } /** - * + * * <code>getRenderer</code> returns the requested rendering API, or the default. - * + * * @return the rendering API or the default. */ public String getRenderer() { @@ -300,7 +299,7 @@ public class PropertiesGameSettings { /** * If the properties file does not contain the setting or was not read properly, the default value is returned. - * + * * @throws InternalError * in all cases */ @@ -311,7 +310,7 @@ public class PropertiesGameSettings { /** * If the properties file does not contain the setting or was not read properly, the default value is returned. - * + * * @throws InternalError * in all cases */ @@ -323,7 +322,7 @@ public class PropertiesGameSettings { /** * <code>getWidth</code> returns the width as read from the properties file. If the properties file does not contain * width or was not read properly, the default width is returned. - * + * * @return the width determined by the properties file, or the default. */ public int getWidth() { @@ -338,7 +337,7 @@ public class PropertiesGameSettings { /** * <code>isFullscreen</code> returns the fullscreen flag as read from the properties file. If the properties file * does not contain the fullscreen flag or was not read properly, the default value is returned. - * + * * @return the fullscreen flag determined by the properties file, or the default. */ public boolean isFullscreen() { @@ -352,7 +351,7 @@ public class PropertiesGameSettings { /** * If the properties file does not contain the setting or was not read properly, the default value is returned. - * + * * @throws InternalError * in all cases */ @@ -367,7 +366,7 @@ public class PropertiesGameSettings { /** * If the properties file does not contain the setting or was not read properly, the default value is returned. - * + * * @throws InternalError * in all cases */ @@ -378,7 +377,7 @@ public class PropertiesGameSettings { /** * If the properties file does not contain the setting or was not read properly, the default value is returned. - * + * * @throws InternalError * in all cases */ @@ -390,35 +389,26 @@ public class PropertiesGameSettings { /** * <code>load</code> attempts to load the properties file defined during instantiation and put all properties in the * table. If there is a problem loading or reading the file, false is returned. If all goes well, true is returned. - * + * * @return the success of the load, true indicated success and false indicates failure. */ public boolean load() { - FileInputStream fin = null; - try { - fin = new FileInputStream(filename); - } catch (final FileNotFoundException e) { - logger.warning("Could not load properties. Creating a new one."); - return false; - } - - try { + try (final FileInputStream fin = new FileInputStream(filename)) { prop.load(fin); - fin.close(); + + // confirm that the properties file has all the data we need. + if (null == prop.getProperty("WIDTH") || null == prop.getProperty("HEIGHT") + || null == prop.getProperty("DEPTH") || null == prop.getProperty("FULLSCREEN")) { + logger.warning("Properties file not complete."); + return false; + } + + logger.finer("Read properties"); + return true; } catch (final IOException e) { logger.warning("Could not load properties. Creating a new one."); return false; } - - // confirm that the properties file has all the data we need. - if (null == prop.getProperty("WIDTH") || null == prop.getProperty("HEIGHT") - || null == prop.getProperty("DEPTH") || null == prop.getProperty("FULLSCREEN")) { - logger.warning("Properties file not complete."); - return false; - } - - logger.finer("Read properties"); - return true; } /** @@ -430,21 +420,20 @@ public class PropertiesGameSettings { /** * Persists current property mappings to designated file, overwriting if file already present. - * + * * @throws IOException * for I/O failures */ public void save() throws IOException { - final FileOutputStream fout = new FileOutputStream(filename); - prop.store(fout, "Game Settings written by " + getClass().getName() + " at " + new java.util.Date()); - - fout.close(); + try (final FileOutputStream fout = new FileOutputStream(filename)) { + prop.store(fout, "Game Settings written by " + getClass().getName() + " at " + new java.util.Date()); + } logger.finer("Saved properties"); } /** * <code>save(int, int, int, int, boolean, String)</code> overwrites the properties file with the given parameters. - * + * * @param width * the width of the resolution. * @param height @@ -595,7 +584,7 @@ public class PropertiesGameSettings { /** * Not implemented. Properties can not store an arbitrary Object in human-readable format. Use set(String, String) * instead. - * + * * @see #set(String, String) * @throws InternalError * in all cases @@ -648,7 +637,7 @@ public class PropertiesGameSettings { /** * save() method which throws only a RuntimeExceptin. - * + * * @throws RuntimeSetting * for IO failure * @see #save() @@ -675,7 +664,7 @@ public class PropertiesGameSettings { * AbstractGameSettings.assignDefaults(propfilename). * <P/> * Property file paths are relative to CLASSPATH element roots. - * + * * @param propFileName * Properties file read as CLASSPATH resource. If you give null, no properties file will be loaded. */ @@ -745,8 +734,9 @@ public class PropertiesGameSettings { try { p.load(istream); } catch (final IOException ioe) { - logger.log(Level.WARNING, "Failed to load customizations from '" + propFileName - + "'. Continuing without customizations.", ioe); + logger.log(Level.WARNING, + "Failed to load customizations from '" + propFileName + "'. Continuing without customizations.", + ioe); return; } Integer i; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/Purpose.java b/ardor3d-examples/src/main/java/com/ardor3d/example/Purpose.java index 0fb9e41..f6ea79d 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/Purpose.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/Purpose.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/applet/JoglBaseApplet.java b/ardor3d-examples/src/main/java/com/ardor3d/example/applet/JoglBaseApplet.java deleted file mode 100644 index 0c3f726..0000000 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/applet/JoglBaseApplet.java +++ /dev/null @@ -1,328 +0,0 @@ -/** - * Copyright (c) 2008-2012 Ardor Labs, Inc. - * - * This file is part of Ardor3D. - * - * Ardor3D is free software: you can redistribute it and/or modify it - * under the terms of its license which may be found in the accompanying - * LICENSE file or at <http://www.ardor3d.com/LICENSE>. - */ - -package com.ardor3d.example.applet; - -import java.applet.Applet; -import java.awt.BorderLayout; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.net.URISyntaxException; -import java.util.concurrent.Callable; - -import javax.media.nativewindow.util.DimensionImmutable; - -import com.ardor3d.annotation.MainThread; -import com.ardor3d.framework.DisplaySettings; -import com.ardor3d.framework.FrameHandler; -import com.ardor3d.framework.Scene; -import com.ardor3d.framework.Updater; -import com.ardor3d.framework.jogl.JoglCanvasRenderer; -import com.ardor3d.framework.jogl.JoglNewtAwtCanvas; -import com.ardor3d.image.util.awt.AWTImageLoader; -import com.ardor3d.input.GrabbedState; -import com.ardor3d.input.Key; -import com.ardor3d.input.MouseButton; -import com.ardor3d.input.PhysicalLayer; -import com.ardor3d.input.control.FirstPersonControl; -import com.ardor3d.input.jogl.JoglNewtFocusWrapper; -import com.ardor3d.input.jogl.JoglNewtKeyboardWrapper; -import com.ardor3d.input.jogl.JoglNewtMouseManager; -import com.ardor3d.input.jogl.JoglNewtMouseWrapper; -import com.ardor3d.input.logical.InputTrigger; -import com.ardor3d.input.logical.KeyReleasedCondition; -import com.ardor3d.input.logical.LogicalLayer; -import com.ardor3d.input.logical.MouseButtonPressedCondition; -import com.ardor3d.input.logical.MouseButtonReleasedCondition; -import com.ardor3d.input.logical.TriggerAction; -import com.ardor3d.input.logical.TwoInputStates; -import com.ardor3d.intersection.PickResults; -import com.ardor3d.math.Ray3; -import com.ardor3d.math.Vector3; -import com.ardor3d.renderer.Camera; -import com.ardor3d.renderer.Renderer; -import com.ardor3d.renderer.TextureRendererFactory; -import com.ardor3d.renderer.jogl.JoglTextureRendererProvider; -import com.ardor3d.renderer.state.ZBufferState; -import com.ardor3d.scenegraph.Node; -import com.ardor3d.util.Constants; -import com.ardor3d.util.ContextGarbageCollector; -import com.ardor3d.util.GameTaskQueue; -import com.ardor3d.util.GameTaskQueueManager; -import com.ardor3d.util.ReadOnlyTimer; -import com.ardor3d.util.Timer; -import com.ardor3d.util.resource.ResourceLocatorTool; -import com.ardor3d.util.resource.SimpleResourceLocator; -import com.ardor3d.util.stat.StatCollector; - -/** - * An example base class for ardor3d/jogl applets. This is not meant to be a "best-practices" applet, just a rough demo - * showing possibilities. As such, there are likely bugs, etc. Please report these. :) - */ -public abstract class JoglBaseApplet extends Applet implements Scene { - - private static final long serialVersionUID = 1L; - - protected DisplaySettings _settings; - protected JoglNewtAwtCanvas _glCanvas; - protected LogicalLayer _logicalLayer; - protected PhysicalLayer _physicalLayer; - protected JoglNewtMouseManager _mouseManager; - - protected FirstPersonControl _controlHandle; - protected Vector3 _worldUp = new Vector3(0, 1, 0); - - protected Thread _gameThread; - protected boolean _running = false; - - protected final Timer _timer = new Timer(); - protected final Node _root = new Node(); - protected final FrameHandler frameHandler = new FrameHandler(_timer); - - @Override - public void init() { - _settings = getSettings(); - setLayout(new BorderLayout(0, 0)); - try { - TextureRendererFactory.INSTANCE.setProvider(new JoglTextureRendererProvider()); - final JoglCanvasRenderer canvasRenderer = new JoglCanvasRenderer(this); - _glCanvas = new JoglNewtAwtCanvas(_settings, canvasRenderer) { - private static final long serialVersionUID = 1L; - - @Override - public final void removeNotify() { - stopJOGL(); - super.removeNotify(); - } - }; - ; - _glCanvas.setSize(getWidth(), getHeight()); - _glCanvas.setFocusable(true); - _glCanvas.requestFocus(); - _glCanvas.setIgnoreRepaint(true); - _glCanvas.addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(final ComponentEvent e) { - GameTaskQueueManager.getManager(_glCanvas.getCanvasRenderer().getRenderContext()).update( - new Callable<Void>() { - public Void call() throws Exception { - final Camera cam = _glCanvas.getCanvasRenderer().getCamera(); - cam.resize(getWidth(), getHeight()); - cam.setFrustumPerspective(cam.getFovY(), getWidth() / (double) getHeight(), - cam.getFrustumNear(), cam.getFrustumFar()); - appletResized(getWidth(), getHeight()); - return null; - } - }); - } - }); - frameHandler.addCanvas(_glCanvas); - frameHandler.addUpdater(new Updater() { - - @Override - @MainThread - public void update(final ReadOnlyTimer timer) { - JoglBaseApplet.this.update(); - } - - @Override - @MainThread - public void init() { - initInput(); - initBaseScene(); - initAppletScene(); - } - }); - add(_glCanvas, BorderLayout.CENTER); - setVisible(true); - startJOGL(); - } catch (final Exception e) { - System.err.println(e); - throw new RuntimeException("Unable to create display"); - } - } - - protected DisplaySettings getSettings() { - return new DisplaySettings(getWidth(), getHeight(), 8, 0); - } - - @Override - public void destroy() { - remove(_glCanvas); - } - - protected void startJOGL() { - frameHandler.init(); - _gameThread = new Thread() { - @Override - public void run() { - _running = true; - gameLoop(); - } - }; - _gameThread.start(); - } - - protected void stopJOGL() { - _running = false; - try { - _gameThread.join(); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - } - - protected void gameLoop() { - while (_running) { - frameHandler.updateFrame(); - Thread.yield(); - } - } - - public void update() { - _timer.update(); - - /** update stats, if enabled. */ - if (Constants.stats) { - StatCollector.update(); - } - updateLogicalLayer(_timer); - - // Execute updateQueue item - GameTaskQueueManager.getManager(_glCanvas.getCanvasRenderer().getRenderContext()) - .getQueue(GameTaskQueue.UPDATE).execute(); - updateAppletScene(_timer); - - // Update controllers/render states/transforms/bounds for rootNode. - _root.updateGeometricState(_timer.getTimePerFrame(), true); - } - - protected void updateLogicalLayer(final ReadOnlyTimer timer) { - // check and execute any input triggers, if we are concerned with input - if (_logicalLayer != null) { - _logicalLayer.checkTriggers(timer.getTimePerFrame()); - } - } - - protected void initInput() { - _mouseManager = new JoglNewtMouseManager(_glCanvas); - _logicalLayer = new LogicalLayer(); - _physicalLayer = new PhysicalLayer(new JoglNewtKeyboardWrapper(_glCanvas), new JoglNewtMouseWrapper(_glCanvas, - _mouseManager), new JoglNewtFocusWrapper(_glCanvas)); - _logicalLayer.registerInput(_glCanvas, _physicalLayer); - _controlHandle = FirstPersonControl.setupTriggers(_logicalLayer, _worldUp, true); - - _logicalLayer.registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.F), new TriggerAction() { - - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - - _glCanvas.getNewtWindow().setFullscreen(!_glCanvas.getNewtWindow().isFullscreen()); - final Camera cam = _glCanvas.getCanvasRenderer().getCamera(); - if (_glCanvas.getNewtWindow().isFullscreen()) { - final DimensionImmutable screenSizeMM = _glCanvas.getNewtWindow().getMainMonitor().getSizeMM(); - cam.resize(screenSizeMM.getWidth(), screenSizeMM.getHeight()); - cam.setFrustumPerspective(cam.getFovY(), - screenSizeMM.getWidth() / (float) screenSizeMM.getHeight(), cam.getFrustumNear(), - cam.getFrustumFar()); - appletResized(screenSizeMM.getWidth(), screenSizeMM.getHeight()); - } else { - cam.resize(getWidth(), getHeight()); - cam.setFrustumPerspective(cam.getFovY(), getWidth() / (float) getHeight(), cam.getFrustumNear(), - cam.getFrustumFar()); - appletResized(getWidth(), getHeight()); - } - } - })); - - _logicalLayer.registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.V), new TriggerAction() { - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - _glCanvas.setVSyncEnabled(true); - } - })); - - _logicalLayer.registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.B), new TriggerAction() { - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - _glCanvas.setVSyncEnabled(false); - } - })); - - _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonPressedCondition(MouseButton.LEFT), - new TriggerAction() { - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - if (_mouseManager.isSetGrabbedSupported()) { - _mouseManager.setGrabbed(GrabbedState.GRABBED); - } - } - })); - - _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonReleasedCondition(MouseButton.LEFT), - new TriggerAction() { - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - if (_mouseManager.isSetGrabbedSupported()) { - _mouseManager.setGrabbed(GrabbedState.NOT_GRABBED); - } - } - })); - } - - protected void initBaseScene() { - // Add our awt based image loader. - AWTImageLoader.registerLoader(); - - // Set the location of our example resources. - try { - final SimpleResourceLocator srl = new SimpleResourceLocator(ResourceLocatorTool.getClassPathResource( - LwjglBaseApplet.class, "com/ardor3d/example/media/")); - ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, srl); - } catch (final URISyntaxException ex) { - ex.printStackTrace(); - } - - // Create a ZBuffer to display pixels closest to the camera above farther ones. - final ZBufferState buf = new ZBufferState(); - buf.setEnabled(true); - buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo); - _root.setRenderState(buf); - } - - public PickResults doPick(final Ray3 pickRay) { - // ignore - return null; - } - - public boolean renderUnto(final Renderer renderer) { - // Execute renderQueue item - GameTaskQueueManager.getManager(_glCanvas.getCanvasRenderer().getRenderContext()) - .getQueue(GameTaskQueue.RENDER).execute(renderer); - - // Clean up card garbage such as textures, vbos, etc. - ContextGarbageCollector.doRuntimeCleanup(renderer); - - renderScene(renderer); - - return true; - } - - protected abstract void initAppletScene(); - - protected void updateAppletScene(final ReadOnlyTimer timer) {}; - - protected void renderScene(final Renderer renderer) { - // Draw the root and all its children. - renderer.draw(_root); - } - - protected void appletResized(final int width, final int height) {} -} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/applet/LwjglBaseApplet.java b/ardor3d-examples/src/main/java/com/ardor3d/example/applet/LwjglBaseApplet.java deleted file mode 100644 index ab1d9f9..0000000 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/applet/LwjglBaseApplet.java +++ /dev/null @@ -1,335 +0,0 @@ -/** - * Copyright (c) 2008-2012 Ardor Labs, Inc. - * - * This file is part of Ardor3D. - * - * Ardor3D is free software: you can redistribute it and/or modify it - * under the terms of its license which may be found in the accompanying - * LICENSE file or at <http://www.ardor3d.com/LICENSE>. - */ - -package com.ardor3d.example.applet; - -import java.applet.Applet; -import java.awt.BorderLayout; -import java.awt.Canvas; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.net.URISyntaxException; -import java.util.concurrent.Callable; - -import org.lwjgl.LWJGLException; -import org.lwjgl.opengl.Display; -import org.lwjgl.opengl.DisplayMode; - -import com.ardor3d.framework.DisplaySettings; -import com.ardor3d.framework.Scene; -import com.ardor3d.framework.lwjgl.LwjglCanvasRenderer; -import com.ardor3d.framework.lwjgl.LwjglDisplayCanvas; -import com.ardor3d.image.util.awt.AWTImageLoader; -import com.ardor3d.input.GrabbedState; -import com.ardor3d.input.Key; -import com.ardor3d.input.MouseButton; -import com.ardor3d.input.PhysicalLayer; -import com.ardor3d.input.control.FirstPersonControl; -import com.ardor3d.input.logical.InputTrigger; -import com.ardor3d.input.logical.KeyReleasedCondition; -import com.ardor3d.input.logical.LogicalLayer; -import com.ardor3d.input.logical.MouseButtonPressedCondition; -import com.ardor3d.input.logical.MouseButtonReleasedCondition; -import com.ardor3d.input.logical.TriggerAction; -import com.ardor3d.input.logical.TwoInputStates; -import com.ardor3d.input.lwjgl.LwjglControllerWrapper; -import com.ardor3d.input.lwjgl.LwjglKeyboardWrapper; -import com.ardor3d.input.lwjgl.LwjglMouseManager; -import com.ardor3d.input.lwjgl.LwjglMouseWrapper; -import com.ardor3d.intersection.PickResults; -import com.ardor3d.math.Ray3; -import com.ardor3d.math.Vector3; -import com.ardor3d.renderer.Camera; -import com.ardor3d.renderer.Renderer; -import com.ardor3d.renderer.TextureRendererFactory; -import com.ardor3d.renderer.lwjgl.LwjglTextureRendererProvider; -import com.ardor3d.renderer.state.ZBufferState; -import com.ardor3d.scenegraph.Node; -import com.ardor3d.util.Constants; -import com.ardor3d.util.ContextGarbageCollector; -import com.ardor3d.util.GameTaskQueue; -import com.ardor3d.util.GameTaskQueueManager; -import com.ardor3d.util.ReadOnlyTimer; -import com.ardor3d.util.Timer; -import com.ardor3d.util.resource.ResourceLocatorTool; -import com.ardor3d.util.resource.SimpleResourceLocator; -import com.ardor3d.util.stat.StatCollector; - -/** - * An example base class for ardor3d/lwjgl applets. This is not meant to be a "best-practices" applet, just a rough demo - * showing possibilities. As such, there are likely bugs, etc. Please report these. :) - */ -public abstract class LwjglBaseApplet extends Applet implements Scene { - - private static final long serialVersionUID = 1L; - - protected DisplaySettings _settings; - protected LwjglDisplayCanvas _glCanvas; - protected LogicalLayer _logicalLayer; - protected PhysicalLayer _physicalLayer; - protected Canvas _displayCanvas; - protected LwjglMouseManager _mouseManager; - - protected FirstPersonControl _controlHandle; - protected Vector3 _worldUp = new Vector3(0, 1, 0); - - protected Thread _gameThread; - protected boolean _running = false; - - protected final Timer _timer = new Timer(); - protected final Node _root = new Node(); - - @Override - public void init() { - _settings = getSettings(); - setLayout(new BorderLayout(0, 0)); - try { - _displayCanvas = new Canvas() { - private static final long serialVersionUID = 1L; - - @Override - public final void addNotify() { - super.addNotify(); - startLWJGL(); - } - - @Override - public final void removeNotify() { - stopLWJGL(); - super.removeNotify(); - } - }; - _displayCanvas.setSize(getWidth(), getHeight()); - add(_displayCanvas, BorderLayout.CENTER); - _displayCanvas.setFocusable(true); - _displayCanvas.requestFocus(); - _displayCanvas.setIgnoreRepaint(true); - _displayCanvas.addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(final ComponentEvent e) { - GameTaskQueueManager.getManager(_glCanvas.getCanvasRenderer().getRenderContext()).update( - new Callable<Void>() { - public Void call() throws Exception { - final Camera cam = _glCanvas.getCanvasRenderer().getCamera(); - cam.resize(getWidth(), getHeight()); - cam.setFrustumPerspective(cam.getFovY(), getWidth() / (double) getHeight(), - cam.getFrustumNear(), cam.getFrustumFar()); - appletResized(getWidth(), getHeight()); - return null; - } - }); - } - }); - setVisible(true); - } catch (final Exception e) { - System.err.println(e); - throw new RuntimeException("Unable to create display"); - } - } - - protected DisplaySettings getSettings() { - return new DisplaySettings(getWidth(), getHeight(), 8, 0); - } - - @Override - public void destroy() { - remove(_displayCanvas); - } - - protected void startLWJGL() { - _gameThread = new Thread() { - @Override - public void run() { - _running = true; - try { - initGL(); - initInput(); - initBaseScene(); - initAppletScene(); - gameLoop(); - } catch (final LWJGLException ex) { - ex.printStackTrace(); - } - } - }; - _gameThread.start(); - } - - protected void stopLWJGL() { - _running = false; - try { - _gameThread.join(); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - } - - protected void gameLoop() { - while (_running) { - update(); - _glCanvas.draw(null); - Thread.yield(); - } - } - - protected void update() { - _timer.update(); - - /** update stats, if enabled. */ - if (Constants.stats) { - StatCollector.update(); - } - - updateLogicalLayer(_timer); - - // Execute updateQueue item - GameTaskQueueManager.getManager(_glCanvas.getCanvasRenderer().getRenderContext()) - .getQueue(GameTaskQueue.UPDATE).execute(); - - updateAppletScene(_timer); - - // Update controllers/render states/transforms/bounds for rootNode. - _root.updateGeometricState(_timer.getTimePerFrame(), true); - } - - protected void updateLogicalLayer(final ReadOnlyTimer timer) { - // check and execute any input triggers, if we are concerned with input - if (_logicalLayer != null) { - _logicalLayer.checkTriggers(timer.getTimePerFrame()); - } - } - - protected void initGL() throws LWJGLException { - TextureRendererFactory.INSTANCE.setProvider(new LwjglTextureRendererProvider()); - final LwjglCanvasRenderer canvasRenderer = new LwjglCanvasRenderer(this); - _glCanvas = new LwjglDisplayCanvas(_displayCanvas, _settings, canvasRenderer); - _glCanvas.init(); - - // by default, we'll keep it vsync'd - _glCanvas.setVSyncEnabled(true); - } - - protected void initInput() { - _mouseManager = new LwjglMouseManager(); - _logicalLayer = new LogicalLayer(); - _physicalLayer = new PhysicalLayer(new LwjglKeyboardWrapper(), new LwjglMouseWrapper(), - new LwjglControllerWrapper(), _glCanvas); - _logicalLayer.registerInput(_glCanvas, _physicalLayer); - _controlHandle = FirstPersonControl.setupTriggers(_logicalLayer, _worldUp, true); - - _logicalLayer.registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.F), new TriggerAction() { - - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - try { - _glCanvas.setFullScreen(!_glCanvas.isFullScreen()); - final Camera cam = _glCanvas.getCanvasRenderer().getCamera(); - if (_glCanvas.isFullScreen()) { - final DisplayMode mode = Display.getDisplayMode(); - cam.resize(mode.getWidth(), mode.getHeight()); - cam.setFrustumPerspective(cam.getFovY(), mode.getWidth() / (float) mode.getHeight(), - cam.getFrustumNear(), cam.getFrustumFar()); - appletResized(mode.getWidth(), mode.getHeight()); - } else { - cam.resize(getWidth(), getHeight()); - cam.setFrustumPerspective(cam.getFovY(), getWidth() / (float) getHeight(), - cam.getFrustumNear(), cam.getFrustumFar()); - appletResized(getWidth(), getHeight()); - } - } catch (final LWJGLException ex) { - ex.printStackTrace(); - } - } - })); - - _logicalLayer.registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.V), new TriggerAction() { - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - _glCanvas.setVSyncEnabled(true); - } - })); - - _logicalLayer.registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.B), new TriggerAction() { - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - _glCanvas.setVSyncEnabled(false); - } - })); - - _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonPressedCondition(MouseButton.LEFT), - new TriggerAction() { - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - if (_mouseManager.isSetGrabbedSupported()) { - _mouseManager.setGrabbed(GrabbedState.GRABBED); - } - } - })); - - _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonReleasedCondition(MouseButton.LEFT), - new TriggerAction() { - public void perform(final com.ardor3d.framework.Canvas source, final TwoInputStates inputState, - final double tpf) { - if (_mouseManager.isSetGrabbedSupported()) { - _mouseManager.setGrabbed(GrabbedState.NOT_GRABBED); - } - } - })); - } - - protected void initBaseScene() { - // Add our awt based image loader. - AWTImageLoader.registerLoader(); - - // Set the location of our example resources. - try { - final SimpleResourceLocator srl = new SimpleResourceLocator(ResourceLocatorTool.getClassPathResource( - LwjglBaseApplet.class, "com/ardor3d/example/media/")); - ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, srl); - } catch (final URISyntaxException ex) { - ex.printStackTrace(); - } - - // Create a ZBuffer to display pixels closest to the camera above farther ones. - final ZBufferState buf = new ZBufferState(); - buf.setEnabled(true); - buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo); - _root.setRenderState(buf); - } - - public PickResults doPick(final Ray3 pickRay) { - // ignore - return null; - } - - public boolean renderUnto(final Renderer renderer) { - // Execute renderQueue item - GameTaskQueueManager.getManager(_glCanvas.getCanvasRenderer().getRenderContext()) - .getQueue(GameTaskQueue.RENDER).execute(renderer); - - // Clean up card garbage such as textures, vbos, etc. - ContextGarbageCollector.doRuntimeCleanup(renderer); - - renderScene(renderer); - - return true; - } - - protected abstract void initAppletScene(); - - protected void updateAppletScene(final ReadOnlyTimer timer) {}; - - protected void renderScene(final Renderer renderer) { - // Draw the root and all its children. - renderer.draw(_root); - } - - protected void appletResized(final int width, final int height) {} -} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/applet/LwjglBoxApplet.java b/ardor3d-examples/src/main/java/com/ardor3d/example/applet/LwjglBoxApplet.java deleted file mode 100644 index 2d43ba7..0000000 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/applet/LwjglBoxApplet.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (c) 2008-2012 Ardor Labs, Inc. - * - * This file is part of Ardor3D. - * - * Ardor3D is free software: you can redistribute it and/or modify it - * under the terms of its license which may be found in the accompanying - * LICENSE file or at <http://www.ardor3d.com/LICENSE>. - */ - -package com.ardor3d.example.applet; - -import com.ardor3d.bounding.BoundingBox; -import com.ardor3d.image.Texture; -import com.ardor3d.math.MathUtils; -import com.ardor3d.math.Matrix3; -import com.ardor3d.math.Vector3; -import com.ardor3d.renderer.state.TextureState; -import com.ardor3d.scenegraph.Spatial; -import com.ardor3d.scenegraph.controller.SpatialController; -import com.ardor3d.scenegraph.shape.Box; -import com.ardor3d.util.TextureManager; - -/** - * The classic "Box Example" as an Ardor3D/LWJGL applet. - */ -public class LwjglBoxApplet extends LwjglBaseApplet { - - private static final long serialVersionUID = 1L; - - @Override - protected void initAppletScene() { - // Make a box... - final Box box = new Box("Box", Vector3.ZERO, 5, 5, 5); - - // Make it a bit more colorful. - box.setRandomColors(); - - // Setup a bounding box for it. - box.setModelBound(new BoundingBox()); - - // Set its location in space. - box.setTranslation(new Vector3(0, 0, -15)); - - // Add to root. - _root.attachChild(box); - - // set it to rotate: - box.addController(new SpatialController<Spatial>() { - private final Vector3 _axis = new Vector3(1, 1, 0.5f).normalizeLocal(); - private final Matrix3 _rotate = new Matrix3(); - private double _angle = 0; - - public void update(final double time, final Spatial caller) { - // update our rotation - _angle = _angle + (_timer.getTimePerFrame() * 25); - if (_angle > 180) { - _angle = -180; - } - - _rotate.fromAngleNormalAxis(_angle * MathUtils.DEG_TO_RAD, _axis); - box.setRotation(_rotate); - } - }); - - // Create a texture from the Ardor3D logo. - final TextureState ts = new TextureState(); - ts.setEnabled(true); - ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true)); - box.setRenderState(ts); - } -} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/BoxExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/BoxExample.java index c000f3b..ca6d103 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/BoxExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/BoxExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/JoglBasicExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/JoglBasicExample.java index 4e6bd8b..f0c23f6 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/JoglBasicExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/JoglBasicExample.java @@ -1,9 +1,9 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * - * Ardor3D is free software: you can redistribute it and/or modify it + * Ardor3D is free software: you can redistribute it and/or modify it * under the terms of its license which may be found in the accompanying * LICENSE file or at <http://www.ardor3d.com/LICENSE>. */ @@ -14,12 +14,13 @@ import java.net.URISyntaxException; import com.ardor3d.bounding.BoundingBox; import com.ardor3d.example.Purpose; +import com.ardor3d.framework.CanvasRenderer; import com.ardor3d.framework.DisplaySettings; import com.ardor3d.framework.Scene; -import com.ardor3d.framework.jogl.JoglCanvas; import com.ardor3d.framework.jogl.JoglCanvasRenderer; +import com.ardor3d.framework.jogl.JoglNewtWindow; import com.ardor3d.image.Texture; -import com.ardor3d.image.util.awt.AWTImageLoader; +import com.ardor3d.image.util.jogl.JoglImageLoader; import com.ardor3d.intersection.PickResults; import com.ardor3d.math.MathUtils; import com.ardor3d.math.Matrix3; @@ -36,13 +37,15 @@ import com.ardor3d.util.TextureManager; import com.ardor3d.util.Timer; import com.ardor3d.util.resource.ResourceLocatorTool; import com.ardor3d.util.resource.SimpleResourceLocator; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; /** * <p> * This jogl-based example is meant to show how to use Ardor3D at the most primitive level, forsaking the use of * ExampleBase and much of our framework classes and interfaces. * </p> - * + * * <p> * Also of note, this example does not allow choosing of properties on launch. It also does not handle input or show any * special debugging. This is to simplify the example to the basic essentials. @@ -54,7 +57,7 @@ maxHeapMemory = 64) public class JoglBasicExample implements Scene { // Our native window, not the gl surface itself. - private final JoglCanvas _canvas; + private final JoglNewtWindow _canvas; // Our timer. private final Timer _timer = new Timer(); @@ -85,28 +88,34 @@ public class JoglBasicExample implements Scene { private void start() { initExample(); + _canvas.addWindowListener(new WindowAdapter() { + @Override + public void windowDestroyNotify(final WindowEvent e) { + final CanvasRenderer cr = _canvas.getCanvasRenderer(); + cr.makeCurrentContext(); + // Done, do cleanup + ContextGarbageCollector.doFinalCleanup(cr.getRenderer()); + cr.releaseCurrentContext(); + } + }); + // Run in this same thread. while (!_exit) { updateExample(); _canvas.draw(null); Thread.yield(); } - _canvas.getCanvasRenderer().makeCurrentContext(); - - // Done, do cleanup - ContextGarbageCollector.doFinalCleanup(_canvas.getCanvasRenderer().getRenderer()); - _canvas.close(); } /** * Setup a jogl canvas and canvas renderer. - * + * * @return the canvas. */ - private JoglCanvas initJogl() { + private JoglNewtWindow initJogl() { final JoglCanvasRenderer canvasRenderer = new JoglCanvasRenderer(this); final DisplaySettings settings = new DisplaySettings(800, 600, 24, 0, 0, 8, 0, 0, false, false); - return new JoglCanvas(canvasRenderer, settings); + return new JoglNewtWindow(canvasRenderer, settings); } /** @@ -136,6 +145,7 @@ public class JoglBasicExample implements Scene { private final Matrix3 _rotate = new Matrix3(); private double _angle = 0; + @Override public void update(final double time, final Box caller) { // update our rotation _angle = _angle + (_timer.getTimePerFrame() * 25); @@ -148,8 +158,8 @@ public class JoglBasicExample implements Scene { } }); - // Add our awt based image loader. - AWTImageLoader.registerLoader(); + // Add our newt based image loader. + JoglImageLoader.registerLoader(); // Set the location of our example resources. try { @@ -191,6 +201,7 @@ public class JoglBasicExample implements Scene { // ------ Scene methods ------ + @Override public boolean renderUnto(final Renderer renderer) { if (!_canvas.isClosing()) { @@ -202,6 +213,7 @@ public class JoglBasicExample implements Scene { return false; } + @Override public PickResults doPick(final Ray3 pickRay) { // Ignore return null; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LineExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LineExample.java index a4fcfa8..8442598 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LineExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LineExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -107,7 +107,7 @@ public class LineExample extends ExampleBase { private Line makeLine(final Grapher grapher, final double min, final double max, final double step) { // This is just one way to make a line... You can also generate the FloatBuffer directly. // Make an array to hold the Vector3 points that will make up our Line. - final ArrayList<Vector3> vertexList = new ArrayList<Vector3>(); + final ArrayList<Vector3> vertexList = new ArrayList<>(); // Step through our range [min, max] by our step amount. for (double x = min; x <= max; x += step) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglBasicExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglBasicExample.java deleted file mode 100644 index 26f5118..0000000 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglBasicExample.java +++ /dev/null @@ -1,213 +0,0 @@ -/** - * Copyright (c) 2008-2012 Ardor Labs, Inc. - * - * This file is part of Ardor3D. - * - * Ardor3D is free software: you can redistribute it and/or modify it - * under the terms of its license which may be found in the accompanying - * LICENSE file or at <http://www.ardor3d.com/LICENSE>. - */ - -package com.ardor3d.example.basic; - -import java.net.URISyntaxException; - -import com.ardor3d.bounding.BoundingBox; -import com.ardor3d.example.Purpose; -import com.ardor3d.framework.DisplaySettings; -import com.ardor3d.framework.Scene; -import com.ardor3d.framework.lwjgl.LwjglCanvas; -import com.ardor3d.framework.lwjgl.LwjglCanvasRenderer; -import com.ardor3d.image.Texture; -import com.ardor3d.image.util.awt.AWTImageLoader; -import com.ardor3d.intersection.PickResults; -import com.ardor3d.math.MathUtils; -import com.ardor3d.math.Matrix3; -import com.ardor3d.math.Ray3; -import com.ardor3d.math.Vector3; -import com.ardor3d.renderer.Renderer; -import com.ardor3d.renderer.state.TextureState; -import com.ardor3d.renderer.state.ZBufferState; -import com.ardor3d.scenegraph.Node; -import com.ardor3d.scenegraph.Spatial; -import com.ardor3d.scenegraph.controller.SpatialController; -import com.ardor3d.scenegraph.shape.Box; -import com.ardor3d.util.ContextGarbageCollector; -import com.ardor3d.util.TextureManager; -import com.ardor3d.util.Timer; -import com.ardor3d.util.resource.ResourceLocatorTool; -import com.ardor3d.util.resource.SimpleResourceLocator; - -/** - * <p> - * This lwjgl-based example is meant to show how to use Ardor3D at the most primitive level, forsaking the use of - * ExampleBase and much of Ardor3D's framework classes and interfaces. - * </p> - * - * <p> - * Also of note, this example does not allow choosing of properties on launch. It also does not handle input or show any - * special debugging. This is to simplify the example to the basic essentials. - * </p> - */ - -@Purpose(htmlDescriptionKey = "com.ardor3d.example.basic.LwjglBasicExample", // -thumbnailPath = "com/ardor3d/example/media/thumbnails/basic_LwjglBasicExample.jpg", // -maxHeapMemory = 64) -public class LwjglBasicExample implements Scene { - - // Our native window, not the gl surface itself. - private final LwjglCanvas _canvas; - - // Our timer. - private final Timer _timer = new Timer(); - - // A boolean allowing us to "pull the plug" from anywhere. - private boolean _exit = false; - - // The root of our scene - private final Node _root = new Node(); - - public static void main(final String[] args) { - final LwjglBasicExample example = new LwjglBasicExample(); - example.start(); - } - - /** - * Constructs the example class, also creating the native window and GL surface. - */ - public LwjglBasicExample() { - _canvas = initLwjgl(); - _canvas.init(); - } - - /** - * Kicks off the example logic, first setting up the scene, then continuously updating and rendering it until exit - * is flagged. Afterwards, the scene and gl surface are cleaned up. - */ - private void start() { - initExample(); - - // Run in this same thread. - while (!_exit) { - updateExample(); - _canvas.draw(null); - Thread.yield(); - } - _canvas.getCanvasRenderer().makeCurrentContext(); - - // Done, do cleanup - ContextGarbageCollector.doFinalCleanup(_canvas.getCanvasRenderer().getRenderer()); - _canvas.close(); - - _canvas.getCanvasRenderer().releaseCurrentContext(); - } - - /** - * Setup an lwjgl canvas and canvas renderer. - * - * @return the canvas. - */ - private LwjglCanvas initLwjgl() { - final LwjglCanvasRenderer canvasRenderer = new LwjglCanvasRenderer(this); - final DisplaySettings settings = new DisplaySettings(800, 600, 24, 0, 0, 8, 0, 0, false, false); - return new LwjglCanvas(settings, canvasRenderer); - } - - /** - * Initialize our scene. - */ - private void initExample() { - _canvas.setTitle("LwjglBasicExample - close window to exit"); - - // Make a box... - final Box _box = new Box("Box", Vector3.ZERO, 5, 5, 5); - - // Make it a bit more colorful. - _box.setRandomColors(); - - // Setup a bounding box for it. - _box.setModelBound(new BoundingBox()); - - // Set its location in space. - _box.setTranslation(new Vector3(0, 0, -15)); - - // Add to root. - _root.attachChild(_box); - - // set it to rotate: - _box.addController(new SpatialController<Spatial>() { - private final Vector3 _axis = new Vector3(1, 1, 0.5f).normalizeLocal(); - private final Matrix3 _rotate = new Matrix3(); - private double _angle = 0; - - public void update(final double time, final Spatial caller) { - // update our rotation - _angle = _angle + (_timer.getTimePerFrame() * 25); - if (_angle > 180) { - _angle = -180; - } - - _rotate.fromAngleNormalAxis(_angle * MathUtils.DEG_TO_RAD, _axis); - _box.setRotation(_rotate); - } - }); - - // Add our awt based image loader. - AWTImageLoader.registerLoader(); - - // Set the location of our example resources. - try { - final SimpleResourceLocator srl = new SimpleResourceLocator(ResourceLocatorTool.getClassPathResource( - LwjglBasicExample.class, "com/ardor3d/example/media/")); - ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, srl); - } catch (final URISyntaxException ex) { - ex.printStackTrace(); - } - - // Create a ZBuffer to display pixels closest to the camera above farther ones. - final ZBufferState buf = new ZBufferState(); - buf.setEnabled(true); - buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo); - _root.setRenderState(buf); - - // Create a texture from the Ardor3D logo. - final TextureState ts = new TextureState(); - ts.setEnabled(true); - ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true)); - _root.setRenderState(ts); - } - - /** - * Update our scene... Check if the window is closing. Then update our timer and finally update the geometric state - * of the root and its children. - */ - private void updateExample() { - if (_canvas.isClosing()) { - _exit = true; - return; - } - - _timer.update(); - - // Update controllers/render states/transforms/bounds for rootNode. - _root.updateGeometricState(_timer.getTimePerFrame(), true); - } - - // ------ Scene methods ------ - - public boolean renderUnto(final Renderer renderer) { - if (!_canvas.isClosing()) { - - // Draw the root and all its children. - renderer.draw(_root); - - return true; - } - return false; - } - - public PickResults doPick(final Ray3 pickRay) { - // Ignore - return null; - } -} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglHeadlessExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglHeadlessExample.java deleted file mode 100644 index e1e8fe4..0000000 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/LwjglHeadlessExample.java +++ /dev/null @@ -1,292 +0,0 @@ -/** - * Copyright (c) 2008-2012 Ardor Labs, Inc. - * - * This file is part of Ardor3D. - * - * Ardor3D is free software: you can redistribute it and/or modify it - * under the terms of its license which may be found in the accompanying - * LICENSE file or at <http://www.ardor3d.com/LICENSE>. - */ - -package com.ardor3d.example.basic; - -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; -import java.net.URISyntaxException; -import java.nio.IntBuffer; -import java.util.concurrent.Callable; - -import javax.swing.ImageIcon; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.SwingConstants; -import javax.swing.WindowConstants; - -import com.ardor3d.bounding.BoundingBox; -import com.ardor3d.example.Purpose; -import com.ardor3d.framework.DisplaySettings; -import com.ardor3d.framework.Scene; -import com.ardor3d.framework.lwjgl.LwjglHeadlessCanvas; -import com.ardor3d.image.Texture; -import com.ardor3d.image.util.awt.AWTImageLoader; -import com.ardor3d.intersection.PickResults; -import com.ardor3d.light.PointLight; -import com.ardor3d.math.ColorRGBA; -import com.ardor3d.math.MathUtils; -import com.ardor3d.math.Matrix3; -import com.ardor3d.math.Ray3; -import com.ardor3d.math.Vector3; -import com.ardor3d.renderer.Renderer; -import com.ardor3d.renderer.state.LightState; -import com.ardor3d.renderer.state.TextureState; -import com.ardor3d.renderer.state.ZBufferState; -import com.ardor3d.scenegraph.Node; -import com.ardor3d.scenegraph.Spatial; -import com.ardor3d.scenegraph.controller.SpatialController; -import com.ardor3d.scenegraph.shape.Box; -import com.ardor3d.util.GameTaskQueue; -import com.ardor3d.util.GameTaskQueueManager; -import com.ardor3d.util.TextureManager; -import com.ardor3d.util.Timer; -import com.ardor3d.util.resource.ResourceLocatorTool; -import com.ardor3d.util.resource.SimpleResourceLocator; - -/** - * <p> - * A demonstration of the LwjglHeadlessCanvas class, which is canvas used to draw Scene data to an offscreen target. - * </p> - * - * <p> - * Also of note, this example does not allow choosing of properties on launch. It also does not handle input or show any - * special debugging. This is to simplify the example to the basic essentials. - * </p> - */ -@Purpose(htmlDescriptionKey = "com.ardor3d.example.basic.LwjglHeadlessExample", // -thumbnailPath = "com/ardor3d/example/media/thumbnails/basic_LwjglHeadlessExample.jpg", // -maxHeapMemory = 64) -public class LwjglHeadlessExample implements Scene { - - // Our headless canvas - private final LwjglHeadlessCanvas canvas; - - // Our timer. - private final Timer timer = new Timer(); - - // The root of our scene - private final Node _root = new Node(); - - // The settings for our canvas - private final DisplaySettings settings; - - // A label we'll set our image into for viewing. - private final JLabel label; - - // The frame we'll show to the user. - private final JFrame frame; - - // The buffered image we'll reuse. - private final BufferedImage labelImage; - - // A int array we'll reuse when transferring data between opengl and the labelImage. - private final int[] tmpData; - - private boolean run = true; - - /** - * Our main entry point to the example. News up the example and calls start. - * - * @param args - * unused. - */ - public static void main(final String[] args) { - final LwjglHeadlessExample example = new LwjglHeadlessExample(); - example.start(); - } - - /** - * Constructs the example class, creating our frame, label, bufferedimage and the headless canvas. - */ - public LwjglHeadlessExample() { - // Setup our headless canvas for rendering. - // settings = new DisplaySettings(800, 600, 0, 0, 0, 16, 0, 4, false, false); // use this to try MSAA - settings = new DisplaySettings(800, 600, 0, 0, 0, 16, 0, 0, false, false); - canvas = new LwjglHeadlessCanvas(settings, this); - canvas.getRenderer().setBackgroundColor(ColorRGBA.BLACK_NO_ALPHA); - - // Set up an image to show our 3d content in. - labelImage = new BufferedImage(settings.getWidth(), settings.getHeight(), BufferedImage.TYPE_INT_ARGB); - tmpData = ((DataBufferInt) labelImage.getRaster().getDataBuffer()).getData(); - - // Set up a frame and label with icon to show our image in. - frame = new JFrame("Headless Example - close window to exit"); - frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - label = new JLabel("View of Headless Content:"); - label.setVerticalTextPosition(SwingConstants.TOP); - label.setHorizontalTextPosition(SwingConstants.CENTER); - label.setIcon(new ImageIcon(labelImage)); - frame.getContentPane().add(label); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent e) { - GameTaskQueueManager.getManager(canvas).render(new Callable<Void>() { - @Override - public Void call() throws Exception { - run = false; - return null; - } - }); - } - }); - } - - /** - * Kicks off the example logic, first setting up the scene, then continuously updating and rendering. - */ - private void start() { - initExample(); - - while (run) { - updateExample(); - - GameTaskQueueManager.getManager(canvas).getQueue(GameTaskQueue.RENDER).execute(); - if (run) { // still run? - canvas.draw(); - } else { - break; - } - - final IntBuffer data = canvas.getDataBuffer(); - - final int width = settings.getWidth(); - - for (int x = settings.getHeight(); --x >= 0;) { - data.get(tmpData, x * width, width); - } - - label.setIcon(new ImageIcon(labelImage)); - } - - canvas.cleanup(); - System.exit(0); - } - - /** - * Initialize our scene. - */ - private void initExample() { - // Make a box... - final Box _box = new Box("Box", Vector3.ZERO, 5, 5, 5); - - // Setup a bounding box for it -- updateModelBound is called automatically internally. - _box.setModelBound(new BoundingBox()); - - // Set its location in space. - _box.setTranslation(new Vector3(0, 0, -25)); - - // Add to root. - _root.attachChild(_box); - - // set it to rotate: - _box.addController(new SpatialController<Spatial>() { - private final Vector3 _axis = new Vector3(1, 1, 0.5f).normalizeLocal(); - private final Matrix3 _rotate = new Matrix3(); - private double _angle = 0; - - public void update(final double time, final Spatial caller) { - // update our rotation - _angle = _angle + (timer.getTimePerFrame() * 25); - if (_angle > 180) { - _angle = -180; - } - - _rotate.fromAngleNormalAxis(_angle * MathUtils.DEG_TO_RAD, _axis); - _box.setRotation(_rotate); - } - }); - - // Add our awt based image loader. - AWTImageLoader.registerLoader(); - - // Set the location of our example resources. - try { - final SimpleResourceLocator srl = new SimpleResourceLocator(ResourceLocatorTool.getClassPathResource( - LwjglHeadlessExample.class, "com/ardor3d/example/media/")); - ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, srl); - } catch (final URISyntaxException ex) { - ex.printStackTrace(); - } - - // Create a ZBuffer to display pixels closest to the camera above farther ones. - final ZBufferState buf = new ZBufferState(); - buf.setEnabled(true); - buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo); - _root.setRenderState(buf); - - // Create a texture from the Ardor3D logo. - final TextureState ts = new TextureState(); - ts.setEnabled(true); - ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true)); - _root.setRenderState(ts); - - // Set up a basic, default light. - final PointLight light = new PointLight(); - light.setDiffuse(new ColorRGBA(0.75f, 0.75f, 0.75f, 0.75f)); - light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)); - light.setLocation(new Vector3(100, 100, 100)); - light.setEnabled(true); - - // Attach the light to a lightState and the lightState to rootNode. - final LightState lightState = new LightState(); - lightState.setEnabled(true); - lightState.attach(light); - _root.setRenderState(lightState); - - } - - // Used for calculating fps. - private double counter = 0; - private int frames = 0; - - /** - * Update our scene... Update our timer, print the current fps (once per second) and finally update the geometric - * state of the root and its children. - */ - private void updateExample() { - timer.update(); - - GameTaskQueueManager.getManager(canvas).getQueue(GameTaskQueue.UPDATE).execute(); - - counter += timer.getTimePerFrame(); - frames++; - if (counter > 1) { - final double fps = (frames / counter); - counter = 0; - frames = 0; - System.out.printf("%7.1f FPS\n", fps); - } - - // Update controllers/render states/transforms/bounds for rootNode. - _root.updateGeometricState(timer.getTimePerFrame(), true); - } - - // ------ Scene methods ------ - - public boolean renderUnto(final Renderer renderer) { - - // Draw the root and all its children. - renderer.draw(_root); - - return true; - } - - public PickResults doPick(final Ray3 pickRay) { - // Ignore - return null; - } -} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/MatrixLookAtExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/MatrixLookAtExample.java index 5bf947d..83787a8 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/MatrixLookAtExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/MatrixLookAtExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -39,7 +39,7 @@ maxHeapMemory = 64) public class MatrixLookAtExample extends ExampleBase { private Mesh targetMesh; - private final List<Mesh> boxes = new ArrayList<Mesh>(); + private final List<Mesh> boxes = new ArrayList<>(); private double time = 0.0; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/MouseManagerExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/MouseManagerExample.java index 6f29e91..8894dd6 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/MouseManagerExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/MouseManagerExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -107,6 +107,7 @@ public class MouseManagerExample extends ExampleBase { _cursor2 = createMouseCursor(awtImageLoader, "com/ardor3d/example/media/input/movedata.gif"); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.H), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { if (useCursorOne) { _mouseManager.setCursor(_cursor1); @@ -118,11 +119,13 @@ public class MouseManagerExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.J), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { _mouseManager.setCursor(MouseCursor.SYSTEM_DEFAULT); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.K), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { if (_mouseManager.isSetPositionSupported()) { _mouseManager.setPosition(0, 0); @@ -132,6 +135,7 @@ public class MouseManagerExample extends ExampleBase { _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonPressedCondition(MouseButton.LEFT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { if (_mouseManager.isSetGrabbedSupported()) { _mouseManager.setGrabbed(GrabbedState.GRABBED); @@ -140,6 +144,7 @@ public class MouseManagerExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonReleasedCondition(MouseButton.LEFT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { if (_mouseManager.isSetGrabbedSupported()) { _mouseManager.setGrabbed(GrabbedState.NOT_GRABBED); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/OrbitCamExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/OrbitCamExample.java index 8d4bc82..cb44ba0 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/OrbitCamExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/OrbitCamExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/RTTShaderExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/RTTShaderExample.java index 25a1fe9..215dc77 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/RTTShaderExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/RTTShaderExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/ShapesExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/ShapesExample.java index 5d11a82..44258fe 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/ShapesExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/ShapesExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -197,6 +197,7 @@ public class ShapesExample extends ExampleBase { // Add mouse-over to show labels _logicalLayer.registerTrigger(new InputTrigger(new MouseMovedCondition(), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { // Put together a pick ray final Vector2 pos = Vector2.fetchTempInstance().set(inputStates.getCurrent().getMouseState().getX(), diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/SwitchNodeExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/SwitchNodeExample.java index 6752d8b..1410eea 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/basic/SwitchNodeExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/basic/SwitchNodeExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -77,6 +77,7 @@ public class SwitchNodeExample extends ExampleBase { _root.getSceneHints().setCullHint(CullHint.Never); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { switchNode.shiftVisibleRight(); } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/Ball.java b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/Ball.java index 9b286fd..b290c94 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/Ball.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/Ball.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BallComponent.java b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BallComponent.java index d6fc129..7de0281 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BallComponent.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BallComponent.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BallSprite.java b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BallSprite.java index 8a8d0ca..5b432fd 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BallSprite.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BallSprite.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BubbleMarkExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BubbleMarkExample.java index 54fd6e7..c7cd8bb 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BubbleMarkExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BubbleMarkExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -18,10 +18,8 @@ import com.ardor3d.framework.CanvasRenderer; import com.ardor3d.framework.DisplaySettings; import com.ardor3d.framework.NativeCanvas; import com.ardor3d.framework.Scene; -import com.ardor3d.framework.jogl.JoglCanvas; import com.ardor3d.framework.jogl.JoglCanvasRenderer; -import com.ardor3d.framework.lwjgl.LwjglCanvas; -import com.ardor3d.framework.lwjgl.LwjglCanvasRenderer; +import com.ardor3d.framework.jogl.JoglNewtWindow; import com.ardor3d.image.Texture; import com.ardor3d.image.TextureStoreFormat; import com.ardor3d.image.util.awt.AWTImageLoader; @@ -49,7 +47,6 @@ import com.ardor3d.util.resource.SimpleResourceLocator; * <p> * There are several system params you can use to modify the test: * <ul> - * <li>-Djogl=true -- use JoglRenderer and canvas instead of Lwjgl.</li> * <li>-Dvsync=true -- ask the canvas to use vertical sync to lock to the monitor refresh rate.</li> * <li>-DnoBallCollide=true -- do not do ball-to-ball collision checks.</li> * <li>-Dballs=# -- change the number of balls to some integer value. (default is 16)</li> @@ -138,15 +135,9 @@ public class BubbleMarkExample implements Scene { * @return the canvas. */ private NativeCanvas initCanvas() { - if ("true".equalsIgnoreCase(System.getProperty("jogl"))) { - final JoglCanvasRenderer canvasRenderer = new JoglCanvasRenderer(this); - final DisplaySettings settings = new DisplaySettings(width, height, 24, 0, 0, 8, 0, 0, false, false); - return new JoglCanvas(canvasRenderer, settings); - } else { - final LwjglCanvasRenderer canvasRenderer = new LwjglCanvasRenderer(this); - final DisplaySettings settings = new DisplaySettings(width, height, 24, 0, 0, 8, 0, 0, false, false); - return new LwjglCanvas(settings, canvasRenderer); - } + final JoglCanvasRenderer canvasRenderer = new JoglCanvasRenderer(this); + final DisplaySettings settings = new DisplaySettings(width, height, 24, 0, 0, 8, 0, 0, false, false); + return new JoglNewtWindow(canvasRenderer, settings); } /** @@ -283,6 +274,7 @@ public class BubbleMarkExample implements Scene { // ------ Scene methods ------ + @Override public boolean renderUnto(final Renderer renderer) { if (!canvas.isClosing()) { @@ -294,6 +286,7 @@ public class BubbleMarkExample implements Scene { return false; } + @Override public PickResults doPick(final Ray3 pickRay) { // Ignore return null; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BubbleMarkUIExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BubbleMarkUIExample.java index 8e8e2d4..16797b9 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BubbleMarkUIExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/benchmark/ball/BubbleMarkUIExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -117,6 +117,7 @@ public class BubbleMarkUIExample extends ExampleBase { Alignment.TOP_LEFT, 5, -5)); vsync.setSelectable(true); vsync.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { _canvas.setVSyncEnabled(vsync.isSelected()); } @@ -128,6 +129,7 @@ public class BubbleMarkUIExample extends ExampleBase { collide.setSelectable(true); collide.setSelected(!skipBallCollide); collide.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { skipBallCollide = !collide.isSelected(); } @@ -145,6 +147,7 @@ public class BubbleMarkUIExample extends ExampleBase { balls16.setSelectable(true); balls16.setSelected(true); balls16.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { resetBalls(16); } @@ -157,6 +160,7 @@ public class BubbleMarkUIExample extends ExampleBase { balls32.setSelectable(true); balls32.setSelected(true); balls32.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { resetBalls(32); } @@ -169,6 +173,7 @@ public class BubbleMarkUIExample extends ExampleBase { balls64.setSelectable(true); balls64.setSelected(true); balls64.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { resetBalls(64); } @@ -181,6 +186,7 @@ public class BubbleMarkUIExample extends ExampleBase { balls128.setSelectable(true); balls128.setSelected(true); balls128.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { resetBalls(128); } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/ExampleScene.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/ExampleScene.java index 9011c80..ac9a77e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/ExampleScene.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/ExampleScene.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/Exit.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/Exit.java index 0019c95..0930ec4 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/Exit.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/Exit.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglAwtDesktopExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglAwtDesktopExample.java index 57128bf..7af08d5 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglAwtDesktopExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglAwtDesktopExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -29,8 +29,8 @@ import com.ardor3d.example.Purpose; import com.ardor3d.framework.Canvas; import com.ardor3d.framework.DisplaySettings; import com.ardor3d.framework.FrameHandler; -import com.ardor3d.framework.jogl.JoglAwtCanvas; import com.ardor3d.framework.jogl.JoglCanvasRenderer; +import com.ardor3d.framework.jogl.awt.JoglAwtCanvas; import com.ardor3d.image.util.awt.AWTImageLoader; import com.ardor3d.input.ControllerWrapper; import com.ardor3d.input.Key; @@ -61,7 +61,7 @@ public class JoglAwtDesktopExample { static MouseCursor _cursor1; static MouseCursor _cursor2; - static Map<Canvas, Boolean> _showCursor1 = new HashMap<Canvas, Boolean>(); + static Map<Canvas, Boolean> _showCursor1 = new HashMap<>(); public static void main(final String[] args) throws Exception { System.setProperty("ardor3d.useMultipleContexts", "true"); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglAwtExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglAwtExample.java index 9b902f1..aae1162 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglAwtExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglAwtExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -27,8 +27,8 @@ import com.ardor3d.example.Purpose; import com.ardor3d.framework.Canvas; import com.ardor3d.framework.DisplaySettings; import com.ardor3d.framework.FrameHandler; -import com.ardor3d.framework.jogl.JoglAwtCanvas; import com.ardor3d.framework.jogl.JoglCanvasRenderer; +import com.ardor3d.framework.jogl.awt.JoglAwtCanvas; import com.ardor3d.image.util.awt.AWTImageLoader; import com.ardor3d.input.ControllerWrapper; import com.ardor3d.input.Key; @@ -58,7 +58,7 @@ public class JoglAwtExample { static MouseCursor _cursor1; static MouseCursor _cursor2; - static Map<Canvas, Boolean> _showCursor1 = new HashMap<Canvas, Boolean>(); + static Map<Canvas, Boolean> _showCursor1 = new HashMap<>(); public static void main(final String[] args) throws Exception { System.setProperty("ardor3d.useMultipleContexts", "true"); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtAwtExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtAwtExample.java index b3778f6..9770e36 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtAwtExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtAwtExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2010 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -28,7 +28,8 @@ import com.ardor3d.framework.Canvas; import com.ardor3d.framework.DisplaySettings; import com.ardor3d.framework.FrameHandler; import com.ardor3d.framework.jogl.JoglCanvasRenderer; -import com.ardor3d.framework.jogl.JoglNewtAwtCanvas; +import com.ardor3d.framework.jogl.awt.JoglNewtAwtCanvas; +import com.ardor3d.image.util.ImageLoaderUtil; import com.ardor3d.image.util.jogl.JoglImageLoader; import com.ardor3d.input.ControllerWrapper; import com.ardor3d.input.Key; @@ -47,6 +48,7 @@ import com.ardor3d.input.logical.TwoInputStates; import com.ardor3d.util.Timer; import com.ardor3d.util.resource.ResourceLocatorTool; import com.ardor3d.util.resource.SimpleResourceLocator; +import com.ardor3d.util.resource.URLResourceSource; /** * This examples demonstrates how to render OpenGL (via JOGL) on a NEWT AWT canvas. FIXME update the thumbnail and the @@ -59,7 +61,7 @@ public class JoglNewtAwtExample { static MouseCursor _cursor1; static MouseCursor _cursor2; - static Map<Canvas, Boolean> _showCursor1 = new HashMap<Canvas, Boolean>(); + static Map<Canvas, Boolean> _showCursor1 = new HashMap<>(); public static void main(final String[] args) throws Exception { System.setProperty("ardor3d.useMultipleContexts", "true"); @@ -99,9 +101,8 @@ public class JoglNewtAwtExample { ex.printStackTrace(); } - final JoglImageLoader joglImageLoader = new JoglImageLoader(); - _cursor1 = createMouseCursor(joglImageLoader, "com/ardor3d/example/media/input/wait_cursor.png"); - _cursor2 = createMouseCursor(joglImageLoader, "com/ardor3d/example/media/input/movedata.gif"); + _cursor1 = createMouseCursor("com/ardor3d/example/media/input/wait_cursor.png"); + _cursor2 = createMouseCursor("com/ardor3d/example/media/input/movedata.gif"); addCanvas(frame, scene1, logicalLayer, frameWork); frame.add(new JLabel( @@ -139,10 +140,11 @@ public class JoglNewtAwtExample { System.exit(0); } - private static MouseCursor createMouseCursor(final JoglImageLoader joglImageLoader, final String resourceName) - throws IOException { - final com.ardor3d.image.Image image = joglImageLoader.load( - ResourceLocatorTool.getClassPathResourceAsStream(JoglNewtAwtExample.class, resourceName), false); + private static MouseCursor createMouseCursor(final String resourceName) throws IOException { + final com.ardor3d.image.Image image = ImageLoaderUtil + .loadImage( + new URLResourceSource(ResourceLocatorTool.getClassPathResource(JoglNewtAwtExample.class, + resourceName)), false); return new MouseCursor("cursor1", image, 0, image.getHeight() - 1); } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtSwtExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtSwtExample.java index 59f54b6..8626d11 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtSwtExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtSwtExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -38,7 +38,8 @@ import com.ardor3d.framework.CanvasRenderer; import com.ardor3d.framework.DisplaySettings; import com.ardor3d.framework.FrameHandler; import com.ardor3d.framework.jogl.JoglCanvasRenderer; -import com.ardor3d.framework.jogl.JoglNewtSwtCanvas; +import com.ardor3d.framework.jogl.swt.JoglNewtSwtCanvas; +import com.ardor3d.image.util.ImageLoaderUtil; import com.ardor3d.image.util.jogl.JoglImageLoader; import com.ardor3d.input.ControllerWrapper; import com.ardor3d.input.GrabbedState; @@ -59,6 +60,7 @@ import com.ardor3d.renderer.Camera; import com.ardor3d.util.Timer; import com.ardor3d.util.resource.ResourceLocatorTool; import com.ardor3d.util.resource.SimpleResourceLocator; +import com.ardor3d.util.resource.URLResourceSource; /** * This examples demonstrates how to render OpenGL (via JOGL) in a NEWT SWT canvas. FIXME update the thumbnail and the @@ -71,7 +73,7 @@ public class JoglNewtSwtExample { static MouseCursor _cursor1; static MouseCursor _cursor2; - static Map<Canvas, Boolean> _showCursor1 = new HashMap<Canvas, Boolean>(); + static Map<Canvas, Boolean> _showCursor1 = new HashMap<>(); private static final Logger logger = Logger.getLogger(JoglNewtSwtExample.class.toString()); private static int i = 0; @@ -248,10 +250,9 @@ public class JoglNewtSwtExample { } })); - final JoglImageLoader joglImageLoader = new JoglImageLoader(); try { - _cursor1 = createMouseCursor(joglImageLoader, "com/ardor3d/example/media/input/wait_cursor.png"); - _cursor2 = createMouseCursor(joglImageLoader, "com/ardor3d/example/media/input/movedata.gif"); + _cursor1 = createMouseCursor("com/ardor3d/example/media/input/wait_cursor.png"); + _cursor2 = createMouseCursor("com/ardor3d/example/media/input/movedata.gif"); } catch (final IOException ioe) { ioe.printStackTrace(); } @@ -259,10 +260,11 @@ public class JoglNewtSwtExample { _showCursor1.put(canvas1, true); } - private static MouseCursor createMouseCursor(final JoglImageLoader joglImageLoader, final String resourceName) - throws IOException { - final com.ardor3d.image.Image image = joglImageLoader.load( - ResourceLocatorTool.getClassPathResourceAsStream(JoglNewtSwtExample.class, resourceName), false); + private static MouseCursor createMouseCursor(final String resourceName) throws IOException { + final com.ardor3d.image.Image image = ImageLoaderUtil + .loadImage( + new URLResourceSource(ResourceLocatorTool.getClassPathResource(JoglNewtSwtExample.class, + resourceName)), false); return new MouseCursor("cursor1", image, 0, image.getHeight() - 1); } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/LwjglAwtExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglSwingExample.java index a45df8f..06b1034 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/LwjglAwtExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglSwingExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -27,8 +27,8 @@ import com.ardor3d.example.Purpose; import com.ardor3d.framework.Canvas; import com.ardor3d.framework.DisplaySettings; import com.ardor3d.framework.FrameHandler; -import com.ardor3d.framework.lwjgl.LwjglAwtCanvas; -import com.ardor3d.framework.lwjgl.LwjglCanvasRenderer; +import com.ardor3d.framework.jogl.JoglCanvasRenderer; +import com.ardor3d.framework.jogl.awt.JoglSwingCanvas; import com.ardor3d.image.util.awt.AWTImageLoader; import com.ardor3d.input.ControllerWrapper; import com.ardor3d.input.Key; @@ -49,16 +49,17 @@ import com.ardor3d.util.resource.ResourceLocatorTool; import com.ardor3d.util.resource.SimpleResourceLocator; /** - * This examples demonstrates how to render OpenGL (via LWJGL) on a AWT canvas. + * This examples demonstrates how to render OpenGL (via JOGL) on a Swing canvas. FIXME: fix the thumbnail and the + * description */ -@Purpose(htmlDescriptionKey = "com.ardor3d.example.canvas.LwjglAwtExample", // -thumbnailPath = "com/ardor3d/example/media/thumbnails/canvas_LwjglAwtExample.jpg", // +@Purpose(htmlDescriptionKey = "com.ardor3d.example.canvas.JoglAwtExample", // +thumbnailPath = "com/ardor3d/example/media/thumbnails/canvas_JoglAwtExample.jpg", // maxHeapMemory = 64) -public class LwjglAwtExample { +public class JoglSwingExample { static MouseCursor _cursor1; static MouseCursor _cursor2; - static Map<Canvas, Boolean> _showCursor1 = new HashMap<Canvas, Boolean>(); + static Map<Canvas, Boolean> _showCursor1 = new HashMap<>(); public static void main(final String[] args) throws Exception { System.setProperty("ardor3d.useMultipleContexts", "true"); @@ -92,7 +93,7 @@ public class LwjglAwtExample { try { final SimpleResourceLocator srl = new SimpleResourceLocator(ResourceLocatorTool.getClassPathResource( - LwjglAwtExample.class, "com/ardor3d/example/media/")); + JoglSwingExample.class, "com/ardor3d/example/media/")); ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, srl); } catch (final URISyntaxException ex) { ex.printStackTrace(); @@ -140,17 +141,17 @@ public class LwjglAwtExample { private static MouseCursor createMouseCursor(final AWTImageLoader awtImageLoader, final String resourceName) throws IOException { final com.ardor3d.image.Image image = awtImageLoader.load( - ResourceLocatorTool.getClassPathResourceAsStream(LwjglAwtExample.class, resourceName), false); + ResourceLocatorTool.getClassPathResourceAsStream(JoglSwingExample.class, resourceName), false); return new MouseCursor("cursor1", image, 0, image.getHeight() - 1); } private static void addCanvas(final JFrame frame, final ExampleScene scene, final LogicalLayer logicalLayer, final FrameHandler frameWork) throws Exception { - final LwjglCanvasRenderer canvasRenderer = new LwjglCanvasRenderer(scene); + final JoglCanvasRenderer canvasRenderer = new JoglCanvasRenderer(scene); final DisplaySettings settings = new DisplaySettings(400, 300, 24, 0, 0, 16, 0, 0, false, false); - final LwjglAwtCanvas theCanvas = new LwjglAwtCanvas(settings, canvasRenderer); + final JoglSwingCanvas theCanvas = new JoglSwingCanvas(settings, canvasRenderer); frame.add(theCanvas); @@ -170,6 +171,7 @@ public class LwjglAwtExample { logicalLayer.registerInput(theCanvas, pl); logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.H), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { if (source != theCanvas) { return; @@ -185,6 +187,7 @@ public class LwjglAwtExample { } })); logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.J), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { if (source != theCanvas) { return; @@ -201,6 +204,7 @@ public class LwjglAwtExample { private static class MyExit implements Exit { private volatile boolean exit = false; + @Override public void exit() { exit = true; } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglSwtExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglSwtExample.java index 3026828..29a4929 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglSwtExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglSwtExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -39,7 +39,8 @@ import com.ardor3d.framework.CanvasRenderer; import com.ardor3d.framework.DisplaySettings; import com.ardor3d.framework.FrameHandler; import com.ardor3d.framework.jogl.JoglCanvasRenderer; -import com.ardor3d.framework.jogl.JoglSwtCanvas; +import com.ardor3d.framework.jogl.swt.JoglSwtCanvas; +import com.ardor3d.image.util.ImageLoaderUtil; import com.ardor3d.image.util.jogl.JoglImageLoader; import com.ardor3d.input.ControllerWrapper; import com.ardor3d.input.GrabbedState; @@ -60,6 +61,7 @@ import com.ardor3d.renderer.Camera; import com.ardor3d.util.Timer; import com.ardor3d.util.resource.ResourceLocatorTool; import com.ardor3d.util.resource.SimpleResourceLocator; +import com.ardor3d.util.resource.URLResourceSource; /** * This examples demonstrates how to render OpenGL (via JOGL) in a SWT canvas. @@ -71,7 +73,7 @@ public class JoglSwtExample { static MouseCursor _cursor1; static MouseCursor _cursor2; - static Map<Canvas, Boolean> _showCursor1 = new HashMap<Canvas, Boolean>(); + static Map<Canvas, Boolean> _showCursor1 = new HashMap<>(); private static final Logger logger = Logger.getLogger(JoglSwtExample.class.toString()); private static int i = 0; @@ -251,11 +253,9 @@ public class JoglSwtExample { : GrabbedState.NOT_GRABBED); } })); - - final JoglImageLoader joglImageLoader = new JoglImageLoader(); try { - _cursor1 = createMouseCursor(joglImageLoader, "com/ardor3d/example/media/input/wait_cursor.png"); - _cursor2 = createMouseCursor(joglImageLoader, "com/ardor3d/example/media/input/movedata.gif"); + _cursor1 = createMouseCursor("com/ardor3d/example/media/input/wait_cursor.png"); + _cursor2 = createMouseCursor("com/ardor3d/example/media/input/movedata.gif"); } catch (final IOException ioe) { ioe.printStackTrace(); } @@ -263,10 +263,10 @@ public class JoglSwtExample { _showCursor1.put(canvas1, true); } - private static MouseCursor createMouseCursor(final JoglImageLoader joglImageLoader, final String resourceName) - throws IOException { - final com.ardor3d.image.Image image = joglImageLoader.load( - ResourceLocatorTool.getClassPathResourceAsStream(JoglSwtExample.class, resourceName), false); + private static MouseCursor createMouseCursor(final String resourceName) throws IOException { + final com.ardor3d.image.Image image = ImageLoaderUtil.loadImage( + new URLResourceSource(ResourceLocatorTool.getClassPathResource(JoglSwtExample.class, resourceName)), + false); return new MouseCursor("cursor1", image, 0, image.getHeight() - 1); } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/LwjglSwtExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/LwjglSwtExample.java deleted file mode 100644 index e564393..0000000 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/LwjglSwtExample.java +++ /dev/null @@ -1,348 +0,0 @@ -/** - * Copyright (c) 2008-2012 Ardor Labs, Inc. - * - * This file is part of Ardor3D. - * - * Ardor3D is free software: you can redistribute it and/or modify it - * under the terms of its license which may be found in the accompanying - * LICENSE file or at <http://www.ardor3d.com/LICENSE>. - */ - -package com.ardor3d.example.canvas; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.ControlListener; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.opengl.GLData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.TabFolder; -import org.eclipse.swt.widgets.TabItem; -import org.lwjgl.LWJGLException; - -import com.ardor3d.example.Purpose; -import com.ardor3d.framework.Canvas; -import com.ardor3d.framework.CanvasRenderer; -import com.ardor3d.framework.FrameHandler; -import com.ardor3d.framework.lwjgl.LwjglCanvasCallback; -import com.ardor3d.framework.lwjgl.LwjglCanvasRenderer; -import com.ardor3d.framework.swt.SwtCanvas; -import com.ardor3d.image.util.awt.AWTImageLoader; -import com.ardor3d.input.ControllerWrapper; -import com.ardor3d.input.GrabbedState; -import com.ardor3d.input.Key; -import com.ardor3d.input.MouseCursor; -import com.ardor3d.input.PhysicalLayer; -import com.ardor3d.input.logical.DummyControllerWrapper; -import com.ardor3d.input.logical.InputTrigger; -import com.ardor3d.input.logical.KeyPressedCondition; -import com.ardor3d.input.logical.LogicalLayer; -import com.ardor3d.input.logical.TriggerAction; -import com.ardor3d.input.logical.TwoInputStates; -import com.ardor3d.input.swt.SwtFocusWrapper; -import com.ardor3d.input.swt.SwtKeyboardWrapper; -import com.ardor3d.input.swt.SwtMouseManager; -import com.ardor3d.input.swt.SwtMouseWrapper; -import com.ardor3d.renderer.Camera; -import com.ardor3d.util.Timer; -import com.ardor3d.util.resource.ResourceLocatorTool; -import com.ardor3d.util.resource.SimpleResourceLocator; - -/** - * This examples demonstrates how to render OpenGL (via LWJGL) on a SWT canvas. - */ -@Purpose(htmlDescriptionKey = "com.ardor3d.example.canvas.LwjglSwtExample", // -thumbnailPath = "com/ardor3d/example/media/thumbnails/canvas_LwjglSwtExample.jpg", // -maxHeapMemory = 64) -public class LwjglSwtExample { - static MouseCursor _cursor1; - static MouseCursor _cursor2; - - static Map<Canvas, Boolean> _showCursor1 = new HashMap<Canvas, Boolean>(); - - private static final Logger logger = Logger.getLogger(LwjglSwtExample.class.toString()); - private static int i = 0; - - public static void main(final String[] args) { - System.setProperty("ardor3d.useMultipleContexts", "true"); - - final Timer timer = new Timer(); - final FrameHandler frameWork = new FrameHandler(timer); - final LogicalLayer logicalLayer = new LogicalLayer(); - - final MyExit exit = new MyExit(); - final ExampleScene scene = new ExampleScene(); - final RotatingCubeGame game = new RotatingCubeGame(scene, exit, logicalLayer, Key.T); - - frameWork.addUpdater(game); - - // INIT SWT STUFF - final Display display = new Display(); - final Shell shell = new Shell(display); - shell.setLayout(new FillLayout()); - - // This is our tab folder, it will be accepting our 3d canvases - final TabFolder tabFolder = new TabFolder(shell, SWT.BORDER); - - // Add a menu item that will create and add a new canvas. - final Menu bar = new Menu(shell, SWT.BAR); - shell.setMenuBar(bar); - - final MenuItem fileItem = new MenuItem(bar, SWT.CASCADE); - fileItem.setText("&Tasks"); - - final Menu submenu = new Menu(shell, SWT.DROP_DOWN); - fileItem.setMenu(submenu); - final MenuItem item = new MenuItem(submenu, SWT.PUSH); - item.addListener(SWT.Selection, new Listener() { - public void handleEvent(final Event e) { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - addNewCanvas(tabFolder, scene, frameWork, logicalLayer); - } - }); - } - }); - item.setText("Add &3d Canvas"); - item.setAccelerator(SWT.MOD1 + '3'); - - AWTImageLoader.registerLoader(); - - try { - final SimpleResourceLocator srl = new SimpleResourceLocator(ResourceLocatorTool.getClassPathResource( - LwjglSwtExample.class, "com/ardor3d/example/media/")); - ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE, srl); - } catch (final URISyntaxException ex) { - ex.printStackTrace(); - } - - addNewCanvas(tabFolder, scene, frameWork, logicalLayer); - - shell.open(); - - game.init(); - // frameWork.init(); - - while (!shell.isDisposed() && !exit.isExit()) { - display.readAndDispatch(); - frameWork.updateFrame(); - Thread.yield(); - - // using the below way makes things really jerky. Not sure how to handle that. - - // if (display.readAndDispatch()) { - // frameWork.updateFrame(); - // } - // else { - // display.sleep(); - // } - } - - display.dispose(); - System.exit(0); - } - - private static void addNewCanvas(final TabFolder tabFolder, final ExampleScene scene, final FrameHandler frameWork, - final LogicalLayer logicalLayer) { - i++; - logger.info("Adding canvas"); - - // Add a new tab to hold our canvas - final TabItem item = new TabItem(tabFolder, SWT.NONE); - item.setText("Canvas #" + i); - tabFolder.setSelection(item); - final Composite canvasParent = new Composite(tabFolder, SWT.NONE); - canvasParent.setLayout(new FillLayout()); - item.setControl(canvasParent); - - final GLData data = new GLData(); - data.depthSize = 8; - data.doubleBuffer = true; - - final SashForm splitter = new SashForm(canvasParent, SWT.HORIZONTAL); - - final SashForm splitterLeft = new SashForm(splitter, SWT.VERTICAL); - final Composite topLeft = new Composite(splitterLeft, SWT.NONE); - topLeft.setLayout(new FillLayout()); - final Composite bottomLeft = new Composite(splitterLeft, SWT.NONE); - bottomLeft.setLayout(new FillLayout()); - - final SashForm splitterRight = new SashForm(splitter, SWT.VERTICAL); - final Composite topRight = new Composite(splitterRight, SWT.NONE); - topRight.setLayout(new FillLayout()); - final Composite bottomRight = new Composite(splitterRight, SWT.NONE); - bottomRight.setLayout(new FillLayout()); - - canvasParent.layout(); - - final SwtCanvas canvas1 = new SwtCanvas(topLeft, SWT.NONE, data); - final LwjglCanvasRenderer lwjglCanvasRenderer1 = new LwjglCanvasRenderer(scene); - addCallback(canvas1, lwjglCanvasRenderer1); - canvas1.setCanvasRenderer(lwjglCanvasRenderer1); - frameWork.addCanvas(canvas1); - canvas1.addControlListener(newResizeHandler(canvas1, lwjglCanvasRenderer1)); - canvas1.setFocus(); - - final SwtCanvas canvas2 = new SwtCanvas(bottomLeft, SWT.NONE, data); - final LwjglCanvasRenderer lwjglCanvasRenderer2 = new LwjglCanvasRenderer(scene); - addCallback(canvas2, lwjglCanvasRenderer2); - canvas2.setCanvasRenderer(lwjglCanvasRenderer2); - frameWork.addCanvas(canvas2); - canvas2.addControlListener(newResizeHandler(canvas2, lwjglCanvasRenderer2)); - - final SwtCanvas canvas3 = new SwtCanvas(topRight, SWT.NONE, data); - final LwjglCanvasRenderer lwjglCanvasRenderer3 = new LwjglCanvasRenderer(scene); - addCallback(canvas3, lwjglCanvasRenderer3); - canvas3.setCanvasRenderer(lwjglCanvasRenderer3); - frameWork.addCanvas(canvas3); - canvas3.addControlListener(newResizeHandler(canvas3, lwjglCanvasRenderer3)); - - final SwtCanvas canvas4 = new SwtCanvas(bottomRight, SWT.NONE, data); - final LwjglCanvasRenderer lwjglCanvasRenderer4 = new LwjglCanvasRenderer(scene); - addCallback(canvas4, lwjglCanvasRenderer4); - canvas4.setCanvasRenderer(lwjglCanvasRenderer4); - frameWork.addCanvas(canvas4); - canvas4.addControlListener(newResizeHandler(canvas4, lwjglCanvasRenderer4)); - - final SwtKeyboardWrapper keyboardWrapper = new SwtKeyboardWrapper(canvas1); - final SwtMouseWrapper mouseWrapper = new SwtMouseWrapper(canvas1); - final SwtFocusWrapper focusWrapper = new SwtFocusWrapper(canvas1); - final SwtMouseManager mouseManager = new SwtMouseManager(canvas1); - final ControllerWrapper controllerWrapper = new DummyControllerWrapper(); - - final PhysicalLayer pl = new PhysicalLayer(keyboardWrapper, mouseWrapper, controllerWrapper, focusWrapper); - - logicalLayer.registerInput(canvas1, pl); - - logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.H), new TriggerAction() { - public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { - if (source != canvas1) { - return; - } - - if (_showCursor1.get(canvas1)) { - mouseManager.setCursor(_cursor1); - } else { - mouseManager.setCursor(_cursor2); - } - - _showCursor1.put(canvas1, !_showCursor1.get(canvas1)); - } - })); - logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.J), new TriggerAction() { - public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { - if (source != canvas1) { - return; - } - - mouseManager.setCursor(MouseCursor.SYSTEM_DEFAULT); - } - })); - logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() { - public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { - if (source != canvas1) { - return; - } - - mouseManager.setGrabbed(mouseManager.getGrabbed() == GrabbedState.NOT_GRABBED ? GrabbedState.GRABBED - : GrabbedState.NOT_GRABBED); - } - })); - - final AWTImageLoader awtImageLoader = new AWTImageLoader(); - try { - _cursor1 = createMouseCursor(awtImageLoader, "com/ardor3d/example/media/input/wait_cursor.png"); - _cursor2 = createMouseCursor(awtImageLoader, "com/ardor3d/example/media/input/movedata.gif"); - } catch (final IOException ioe) { - ioe.printStackTrace(); - } - - _showCursor1.put(canvas1, true); - } - - private static void addCallback(final SwtCanvas canvas, final LwjglCanvasRenderer renderer) { - renderer.setCanvasCallback(new LwjglCanvasCallback() { - @Override - public void makeCurrent() throws LWJGLException { - canvas.setCurrent(); - } - - @Override - public void releaseContext() throws LWJGLException { - ; // do nothing? - } - }); - } - - private static MouseCursor createMouseCursor(final AWTImageLoader awtImageLoader, final String resourceName) - throws IOException { - final com.ardor3d.image.Image image = awtImageLoader.load( - ResourceLocatorTool.getClassPathResourceAsStream(LwjglSwtExample.class, resourceName), false); - - return new MouseCursor("cursor1", image, 0, image.getHeight() - 1); - } - - static ControlListener newResizeHandler(final SwtCanvas swtCanvas, final CanvasRenderer canvasRenderer) { - final ControlListener retVal = new ControlListener() { - public void controlMoved(final ControlEvent e) {} - - public void controlResized(final ControlEvent event) { - final Rectangle size = swtCanvas.getClientArea(); - if ((size.width == 0) && (size.height == 0)) { - return; - } - final float aspect = (float) size.width / (float) size.height; - final Camera camera = canvasRenderer.getCamera(); - if (camera != null) { - final double fovY = camera.getFovY(); - final double near = camera.getFrustumNear(); - final double far = camera.getFrustumFar(); - camera.setFrustumPerspective(fovY, aspect, near, far); - camera.resize(size.width, size.height); - } - } - }; - return retVal; - } - - private static class MyExit implements Exit { - private volatile boolean exit = false; - - public void exit() { - exit = true; - } - - public boolean isExit() { - return exit; - } - } -} - -// class LwjglSwtModule extends AbstractModule { -// public LwjglSwtModule() {} -// -// @Override -// protected void configure() { -// // enforce a single instance of SwtKeyboardWrapper will handle both the KeyListener and the KeyboardWrapper -// // interfaces -// bind(SwtKeyboardWrapper.class).in(Scopes.SINGLETON); -// bind(KeyboardWrapper.class).to(SwtKeyboardWrapper.class); -// bind(KeyListener.class).to(SwtKeyboardWrapper.class); -// -// bind(MouseWrapper.class).to(SwtMouseWrapper.class); -// } -// }
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/RotatingCubeGame.java b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/RotatingCubeGame.java index 395a411..e69363e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/RotatingCubeGame.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/RotatingCubeGame.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -64,6 +64,7 @@ public class RotatingCubeGame implements Updater { this.toggleRotationKey = toggleRotationKey; } + @Override @MainThread public void init() { if (inited) { @@ -119,34 +120,40 @@ public class RotatingCubeGame implements Updater { control.setMoveSpeed(MOVE_SPEED); logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ESCAPE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { exit.exit(); } })); logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(toggleRotationKey), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { toggleRotation(); } })); logicalLayer.registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.U), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { toggleRotation(); } })); logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { resetCamera(source); } })); logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { lookAtZero(source); } })); logicalLayer.registerTrigger(new InputTrigger(new AnyKeyCondition(), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { final InputState current = inputStates.getCurrent(); @@ -172,6 +179,7 @@ public class RotatingCubeGame implements Updater { rotationSign *= -1; } + @Override @MainThread public void update(final ReadOnlyTimer timer) { final double tpf = timer.getTimePerFrame(); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/collision/CollisionTreeExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/collision/CollisionTreeExample.java index e2e8196..377d6ba 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/collision/CollisionTreeExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/collision/CollisionTreeExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -81,6 +81,7 @@ public class CollisionTreeExample extends ExampleBase { torus.addController(new SpatialController<PQTorus>() { private double currentTime; + @Override public void update(final double time, final PQTorus caller) { currentTime += time * 0.2; final ReadOnlyVector3 t = caller.getTranslation(); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/collision/ManyCollisionsExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/collision/ManyCollisionsExample.java index 95133d7..64e93cd 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/collision/ManyCollisionsExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/collision/ManyCollisionsExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/BloomExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/BloomExample.java index 643dde5..d229dbe 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/BloomExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/BloomExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -92,6 +92,7 @@ public class BloomExample extends ExampleBase { _canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 0, 0), Vector3.UNIT_Y); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { updateText(); } @@ -147,72 +148,84 @@ public class BloomExample extends ExampleBase { _passManager.add(renderPass); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setEnabled(!bloomRenderPass.isEnabled()); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setBlurSize(bloomRenderPass.getBlurSize() - 0.001f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setBlurSize(bloomRenderPass.getBlurSize() + 0.001f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setExposurePow(bloomRenderPass.getExposurePow() - 1.0f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setExposurePow(bloomRenderPass.getExposurePow() + 1.0f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setExposureCutoff(bloomRenderPass.getExposureCutoff() - 0.1f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setExposureCutoff(bloomRenderPass.getExposureCutoff() + 0.1f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setBlurIntensityMultiplier(bloomRenderPass.getBlurIntensityMultiplier() - 0.1f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setBlurIntensityMultiplier(bloomRenderPass.getBlurIntensityMultiplier() + 0.1f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.resetParameters(); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.J), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setUseCurrentScene(!bloomRenderPass.useCurrentScene()); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { bloomRenderPass.setUseSeparateConvolution(!bloomRenderPass.isUseSeparateConvolution()); updateText(); @@ -250,6 +263,7 @@ public class BloomExample extends ExampleBase { private double timer = 0; private final Matrix3 rotation = new Matrix3(); + @Override public void update(final double time, final Torus caller) { timer += time * 0.5; caller.setTranslation(Math.sin(timer) * 40.0, Math.sin(timer) * 40.0, Math.cos(timer) * 40.0); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ExtrusionExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ExtrusionExample.java index deb199f..acff3e7 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ExtrusionExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ExtrusionExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -10,6 +10,7 @@ package com.ardor3d.example.effect; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -22,7 +23,6 @@ import com.ardor3d.scenegraph.Line; import com.ardor3d.scenegraph.shape.Extrusion; import com.ardor3d.spline.CatmullRomSpline; import com.ardor3d.spline.Curve; -import com.google.common.collect.Lists; /** * A demonstration of the Extrusion class - showing how a set of point can be converted into a 3d shape. @@ -42,7 +42,7 @@ public class ExtrusionExample extends ExampleBase { _canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 0, 80)); _canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(), Vector3.UNIT_Y); - final List<ReadOnlyVector3> path = Lists.newArrayList(); + final List<ReadOnlyVector3> path = new ArrayList<>(); path.add(new Vector3(0, 0, 0)); path.add(new Vector3(0, 0, 4)); path.add(new Vector3(1, 0, 8)); @@ -97,7 +97,7 @@ public class ExtrusionExample extends ExampleBase { private Line createLineStrip(final boolean loop) { // Create a line with our example "makeLine" method. See method below. - final ReadOnlyVector3[] vectors = { // + final ReadOnlyVector3[] vectors = { // new Vector3(0, 0, 0), // new Vector3(5, 0, 0), // new Vector3(5, 5, 0), // diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/NewDynamicSmokerExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/NewDynamicSmokerExample.java index 739beba..4eee5ca 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/NewDynamicSmokerExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/NewDynamicSmokerExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -127,6 +127,7 @@ public class NewDynamicSmokerExample extends ExampleBase { FirstPersonControl.removeTriggers(_logicalLayer, _controlHandle); _logicalLayer.registerTrigger(new InputTrigger(new MouseMovedCondition(), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { final MouseState mouse = inputStates.getCurrent().getMouseState(); mouseLoc.set(mouse.getX(), mouse.getY()); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParallelSplitShadowMapExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParallelSplitShadowMapExample.java index 57d703f..56dc5f7 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParallelSplitShadowMapExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParallelSplitShadowMapExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.effect;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass;
import com.ardor3d.extension.shadow.map.ShadowCasterManager;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.image.Texture2D;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.light.Light;
import com.ardor3d.light.PointLight;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.pass.BasicPassManager;
import com.ardor3d.renderer.pass.RenderPass;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.BlendState;
import com.ardor3d.renderer.state.BlendState.TestFunction;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.ColorMaterial;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.Spatial;
import com.ardor3d.scenegraph.controller.SpatialController;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.hint.TextureCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Torus;
import com.ardor3d.scenegraph.visitor.UpdateModelBoundVisitor;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing the parallel split shadow mapping technique. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.effect.ParallelSplitShadowMapExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/effect_ParallelSplitShadowMapExample.jpg", //
maxHeapMemory = 64)
public class ParallelSplitShadowMapExample extends ExampleBase {
/** Pssm shadow map pass. */
private ParallelSplitShadowMapPass _pssmPass;
/** Pass manager. */
private BasicPassManager _passManager;
/** Quads used for debug showing shadowmaps. */
private Quad _orthoQuad[];
/** Flag for turning on/off light movement. */
private boolean _updateLight = false;
/** Temp vec for updating light pos. */
private final Vector3 lightPosition = new Vector3(10000, 5000, 10000);
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[12];
/** Flag to make sure quads are updated on reinitialization of shadow renderer */
private boolean _quadsDirty = true;
/** Console fps output */
private double counter = 0;
private int frames = 0;
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(final String[] args) {
start(ParallelSplitShadowMapExample.class);
}
/**
* Update the PassManager and light.
*
* @param timer
* the application timer
*/
@Override
protected void updateExample(final ReadOnlyTimer timer) {
_passManager.updatePasses(timer.getTimePerFrame());
if (_updateLight) {
final double time = timer.getTimeInSeconds() * 0.2;
lightPosition.set(Math.sin(time) * 10000.0, 5000.0, Math.cos(time) * 10000.0);
}
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = (frames / counter);
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
}
/**
* Initialize pssm if needed. Update light position. Render scene.
*
* @param renderer
* the renderer
*/
@Override
protected void renderExample(final Renderer renderer) {
if (!_pssmPass.isInitialised()) {
_pssmPass.init(renderer);
}
updateQuadTextures(renderer);
// Update the shadowpass "light" position. Iow it's camera.
final Light light = _lightState.get(0);
if (light instanceof PointLight) {
((PointLight) light).setLocation(lightPosition);
} else if (light instanceof DirectionalLight) {
((DirectionalLight) light).setDirection(lightPosition.normalize(null).negateLocal());
}
_passManager.renderPasses(renderer);
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Parallel Split Shadow Maps - Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(250, 200, -250));
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
45.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ (float) _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0, 10000);
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 0, 0), Vector3.UNIT_Y);
_controlHandle.setMoveSpeed(200);
// Setup some standard states for the scene.
final CullState cullFrontFace = new CullState();
cullFrontFace.setEnabled(true);
cullFrontFace.setCullFace(CullState.Face.Back);
_root.setRenderState(cullFrontFace);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true));
_root.setRenderState(ts);
final MaterialState ms = new MaterialState();
ms.setColorMaterial(ColorMaterial.Diffuse);
_root.setRenderState(ms);
_passManager = new BasicPassManager();
// setup some quads for debug viewing.
final RenderPass renderPass = new RenderPass();
final int quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
_orthoQuad = new Quad[ParallelSplitShadowMapPass._MAX_SPLITS];
for (int i = 0; i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) {
_orthoQuad[i] = new Quad("OrthoQuad", quadSize, quadSize);
_orthoQuad[i].setTranslation(new Vector3((quadSize / 2 + 5) + (quadSize + 5) * i, (quadSize / 2 + 5), 1));
_orthoQuad[i].getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
_orthoQuad[i].getSceneHints().setLightCombineMode(LightCombineMode.Off);
_orthoQuad[i].getSceneHints().setTextureCombineMode(TextureCombineMode.Replace);
_orthoQuad[i].getSceneHints().setCullHint(CullHint.Never);
renderPass.add(_orthoQuad[i]);
}
// Create scene objects.
setupTerrain();
final RenderPass rootPass = new RenderPass();
rootPass.add(_root);
_lightState.detachAll();
final DirectionalLight light = new DirectionalLight();
// final PointLight light = new PointLight();
light.setEnabled(true);
_lightState.attach(light);
// Create pssm pass
_pssmPass = new ParallelSplitShadowMapPass(light, 1024, 3);
_pssmPass.add(_root);
_pssmPass.setUseSceneTexturing(true);
_pssmPass.setUseObjectCullFace(true);
final Node occluders = setupOccluders();
ShadowCasterManager.INSTANCE.addSpatial(occluders);
// Populate passmanager with passes.
_passManager.add(rootPass);
_passManager.add(_pssmPass);
_passManager.add(renderPass);
// Setup textfields for presenting example info.
final Node textNodes = new Node("Text");
renderPass.add(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight();
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - (i + 1) * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
// Register keyboard triggers for manipulating example
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setDrawShaderDebug(!_pssmPass.isDrawShaderDebug());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_updateLight = !_updateLight;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setUpdateMainCamera(!_pssmPass.isUpdateMainCamera());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setDrawDebug(!_pssmPass.isDrawDebug());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (_pssmPass.getNumOfSplits() > ParallelSplitShadowMapPass._MIN_SPLITS) {
_pssmPass.setNumOfSplits(_pssmPass.getNumOfSplits() - 1);
updateText();
_quadsDirty = true;
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (_pssmPass.getNumOfSplits() < ParallelSplitShadowMapPass._MAX_SPLITS) {
_pssmPass.setNumOfSplits(_pssmPass.getNumOfSplits() + 1);
updateText();
_quadsDirty = true;
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (_pssmPass.getShadowMapSize() > 1) {
_pssmPass.setShadowMapSize(_pssmPass.getShadowMapSize() / 2);
updateText();
_quadsDirty = true;
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (_pssmPass.getShadowMapSize() < 2048) {
_pssmPass.setShadowMapSize(_pssmPass.getShadowMapSize() * 2);
updateText();
_quadsDirty = true;
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final double maxShadowDistance = _pssmPass.getMaxShadowDistance();
if (maxShadowDistance > 200.0) {
_pssmPass.setMaxShadowDistance(maxShadowDistance - 100.0);
updateText();
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final double maxShadowDistance = _pssmPass.getMaxShadowDistance();
_pssmPass.setMaxShadowDistance(maxShadowDistance + 100.0);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setNumOfSplits(1);
_pssmPass.setShadowMapSize(1024);
updateText();
_quadsDirty = true;
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.I), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setNumOfSplits(3);
_pssmPass.setShadowMapSize(512);
updateText();
_quadsDirty = true;
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.J), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setUseSceneTexturing(!_pssmPass.isUseSceneTexturing());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.K), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setUseObjectCullFace(!_pssmPass.isUseObjectCullFace());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setEnabled(!_pssmPass.isEnabled());
updateText();
_quadsDirty = true;
}
}));
// Make sure all boundings are updated.
_root.acceptVisitor(new UpdateModelBoundVisitor(), false);
}
/**
* Setup debug quads to render pssm shadowmaps.
*/
private void updateQuadTextures(final Renderer r) {
if (!_quadsDirty) {
return;
}
_quadsDirty = false;
_pssmPass.reinit(r);
for (int i = 0; i < _pssmPass.getNumOfSplits(); i++) {
final TextureState screen = new TextureState();
final Texture2D copy = new Texture2D();
copy.setTextureKey(_pssmPass.getShadowMapTexture(i).getTextureKey());
screen.setTexture(copy);
_orthoQuad[i].setRenderState(screen);
_orthoQuad[i].getSceneHints().setCullHint(CullHint.Never);
_orthoQuad[i].updateGeometricState(0.0);
}
for (int i = _pssmPass.getNumOfSplits(); i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) {
_orthoQuad[i].getSceneHints().setCullHint(CullHint.Always);
}
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[0] Debug shader draw: " + _pssmPass.isDrawShaderDebug());
_exampleInfo[1].setText("[1] Update light: " + _updateLight);
_exampleInfo[2].setText("[2] Update main camera: " + _pssmPass.isUpdateMainCamera());
_exampleInfo[3].setText("[3] Debug draw: " + _pssmPass.isDrawDebug());
_exampleInfo[4].setText("[4/5] Number of splits: " + _pssmPass.getNumOfSplits());
_exampleInfo[5].setText("[6/7] Shadow map size: " + _pssmPass.getShadowMapSize());
_exampleInfo[6].setText("[8/9] Max shadow distance: " + _pssmPass.getMaxShadowDistance());
_exampleInfo[7].setText("[U] Setup 1 split of size 1024");
_exampleInfo[8].setText("[I] Setup 3 splits of size 512");
_exampleInfo[9].setText("[J] Use scene texturing: " + _pssmPass.isUseSceneTexturing());
_exampleInfo[10].setText("[K] Use object cull face: " + _pssmPass.isUseObjectCullFace());
_exampleInfo[11].setText("[SPACE] toggle PSSM pass: " + (_pssmPass.isEnabled() ? "enabled" : "disabled"));
}
/**
* Setup terrain.
*/
private void setupTerrain() {
final Box box = new Box("box", new Vector3(), 10000, 10, 10000);
box.setModelBound(new BoundingBox());
box.addController(new SpatialController<Box>() {
double timer = 0;
public void update(final double time, final Box caller) {
timer += time;
caller.setTranslation(Math.sin(timer) * 20.0, 0, Math.cos(timer) * 20.0);
}
});
_root.attachChild(box);
}
/**
* Setup occluders.
*/
private Node setupOccluders() {
final Node occluders = new Node("occs");
_root.attachChild(occluders);
for (int i = 0; i < 30; i++) {
final double w = Math.random() * 40 + 10;
final double y = Math.random() * 20 + 10;
final Box b = new Box("box", new Vector3(), w, y, w);
b.setModelBound(new BoundingBox());
final double x = Math.random() * 1000 - 500;
final double z = Math.random() * 1000 - 500;
b.setTranslation(new Vector3(x, y, z));
occluders.attachChild(b);
}
final Torus torusWithoutShadows = new Torus("torus", 32, 10, 15.0f, 20.0f);
torusWithoutShadows.setModelBound(new BoundingBox());
torusWithoutShadows.getSceneHints().setCastsShadows(false);
torusWithoutShadows.setTranslation(0, 50, -100);
occluders.attachChild(torusWithoutShadows);
final Torus torus = new Torus("torus", 64, 12, 10.0f, 15.0f);
torus.setModelBound(new BoundingBox());
occluders.attachChild(torus);
torus.addController(new SpatialController<Torus>() {
double timer = 0;
Matrix3 rotation = new Matrix3();
public void update(final double time, final Torus caller) {
timer += time;
caller.setTranslation(Math.sin(timer) * 40.0, Math.sin(timer) * 50.0 + 20.0, Math.cos(timer) * 40.0);
rotation.fromAngles(timer * 0.4, timer * 0.4, timer * 0.4);
caller.setRotation(rotation);
}
});
// Attach "billboard" with an alpha test.
occluders.attachChild(makeBillBoard());
return occluders;
}
private Spatial makeBillBoard() {
final Node billboard = new Node("bb");
billboard.getSceneHints().setRenderBucketType(RenderBucketType.Transparent);
final Quad q1 = new Quad("font block", 150, 200);
q1.setTranslation(0, 80, 0);
q1.setModelBound(new BoundingBox());
final CullState cs = new CullState();
cs.setCullFace(CullState.Face.None);
q1.setRenderState(cs);
billboard.attachChild(q1);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("fonts/OkasaSansSerif-35-medium-regular_00.png",
Texture.MinificationFilter.Trilinear, true));
billboard.setRenderState(ts);
final BlendState bs = new BlendState();
bs.setEnabled(true);
bs.setBlendEnabled(false);
bs.setTestEnabled(true);
bs.setTestFunction(TestFunction.GreaterThan);
bs.setReference(0.7f);
billboard.setRenderState(bs);
return billboard;
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2018 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.effect;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass;
import com.ardor3d.extension.shadow.map.ShadowCasterManager;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.image.Texture2D;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.light.Light;
import com.ardor3d.light.PointLight;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.pass.BasicPassManager;
import com.ardor3d.renderer.pass.RenderPass;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.BlendState;
import com.ardor3d.renderer.state.BlendState.TestFunction;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.ColorMaterial;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.Spatial;
import com.ardor3d.scenegraph.controller.SpatialController;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.hint.TextureCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Torus;
import com.ardor3d.scenegraph.visitor.UpdateModelBoundVisitor;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing the parallel split shadow mapping technique. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.effect.ParallelSplitShadowMapExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/effect_ParallelSplitShadowMapExample.jpg", //
maxHeapMemory = 64)
public class ParallelSplitShadowMapExample extends ExampleBase {
/** Pssm shadow map pass. */
private ParallelSplitShadowMapPass _pssmPass;
/** Pass manager. */
private BasicPassManager _passManager;
/** Quads used for debug showing shadowmaps. */
private Quad _orthoQuad[];
/** Flag for turning on/off light movement. */
private boolean _updateLight = false;
/** Temp vec for updating light pos. */
private final Vector3 lightPosition = new Vector3(10000, 5000, 10000);
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[12];
/** Flag to make sure quads are updated on reinitialization of shadow renderer */
private boolean _quadsDirty = true;
/** Console fps output */
private double counter = 0;
private int frames = 0;
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(final String[] args) {
start(ParallelSplitShadowMapExample.class);
}
/**
* Update the PassManager and light.
*
* @param timer
* the application timer
*/
@Override
protected void updateExample(final ReadOnlyTimer timer) {
_passManager.updatePasses(timer.getTimePerFrame());
if (_updateLight) {
final double time = timer.getTimeInSeconds() * 0.2;
lightPosition.set(Math.sin(time) * 10000.0, 5000.0, Math.cos(time) * 10000.0);
}
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = (frames / counter);
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
}
/**
* Initialize pssm if needed. Update light position. Render scene.
*
* @param renderer
* the renderer
*/
@Override
protected void renderExample(final Renderer renderer) {
if (!_pssmPass.isInitialised()) {
_pssmPass.init(renderer);
}
updateQuadTextures(renderer);
// Update the shadowpass "light" position. Iow it's camera.
final Light light = _lightState.get(0);
if (light instanceof PointLight) {
((PointLight) light).setLocation(lightPosition);
} else if (light instanceof DirectionalLight) {
((DirectionalLight) light).setDirection(lightPosition.normalize(null).negateLocal());
}
_passManager.renderPasses(renderer);
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Parallel Split Shadow Maps - Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(250, 200, -250));
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
45.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ (float) _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0, 10000);
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 0, 0), Vector3.UNIT_Y);
_controlHandle.setMoveSpeed(200);
// Setup some standard states for the scene.
final CullState cullFrontFace = new CullState();
cullFrontFace.setEnabled(true);
cullFrontFace.setCullFace(CullState.Face.Back);
_root.setRenderState(cullFrontFace);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true));
_root.setRenderState(ts);
final MaterialState ms = new MaterialState();
ms.setColorMaterial(ColorMaterial.Diffuse);
_root.setRenderState(ms);
_passManager = new BasicPassManager();
// setup some quads for debug viewing.
final RenderPass renderPass = new RenderPass();
final int quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
_orthoQuad = new Quad[ParallelSplitShadowMapPass._MAX_SPLITS];
for (int i = 0; i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) {
_orthoQuad[i] = new Quad("OrthoQuad", quadSize, quadSize);
_orthoQuad[i].setTranslation(new Vector3((quadSize / 2 + 5) + (quadSize + 5) * i, (quadSize / 2 + 5), 1));
_orthoQuad[i].getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
_orthoQuad[i].getSceneHints().setLightCombineMode(LightCombineMode.Off);
_orthoQuad[i].getSceneHints().setTextureCombineMode(TextureCombineMode.Replace);
_orthoQuad[i].getSceneHints().setCullHint(CullHint.Never);
renderPass.add(_orthoQuad[i]);
}
// Create scene objects.
setupTerrain();
final RenderPass rootPass = new RenderPass();
rootPass.add(_root);
_lightState.detachAll();
final DirectionalLight light = new DirectionalLight();
// final PointLight light = new PointLight();
light.setEnabled(true);
_lightState.attach(light);
// Create pssm pass
_pssmPass = new ParallelSplitShadowMapPass(light, 1024, 3);
_pssmPass.add(_root);
_pssmPass.setUseSceneTexturing(true);
_pssmPass.setUseObjectCullFace(true);
final Node occluders = setupOccluders();
ShadowCasterManager.INSTANCE.addSpatial(occluders);
// Populate passmanager with passes.
_passManager.add(rootPass);
_passManager.add(_pssmPass);
_passManager.add(renderPass);
// Setup textfields for presenting example info.
final Node textNodes = new Node("Text");
renderPass.add(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight();
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - (i + 1) * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
// Register keyboard triggers for manipulating example
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setDrawShaderDebug(!_pssmPass.isDrawShaderDebug());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_updateLight = !_updateLight;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setUpdateMainCamera(!_pssmPass.isUpdateMainCamera());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setDrawDebug(!_pssmPass.isDrawDebug());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (_pssmPass.getNumOfSplits() > ParallelSplitShadowMapPass._MIN_SPLITS) {
_pssmPass.setNumOfSplits(_pssmPass.getNumOfSplits() - 1);
updateText();
_quadsDirty = true;
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (_pssmPass.getNumOfSplits() < ParallelSplitShadowMapPass._MAX_SPLITS) {
_pssmPass.setNumOfSplits(_pssmPass.getNumOfSplits() + 1);
updateText();
_quadsDirty = true;
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (_pssmPass.getShadowMapSize() > 1) {
_pssmPass.setShadowMapSize(_pssmPass.getShadowMapSize() / 2);
updateText();
_quadsDirty = true;
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (_pssmPass.getShadowMapSize() < 2048) {
_pssmPass.setShadowMapSize(_pssmPass.getShadowMapSize() * 2);
updateText();
_quadsDirty = true;
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final double maxShadowDistance = _pssmPass.getMaxShadowDistance();
if (maxShadowDistance > 200.0) {
_pssmPass.setMaxShadowDistance(maxShadowDistance - 100.0);
updateText();
}
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final double maxShadowDistance = _pssmPass.getMaxShadowDistance();
_pssmPass.setMaxShadowDistance(maxShadowDistance + 100.0);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setNumOfSplits(1);
_pssmPass.setShadowMapSize(1024);
updateText();
_quadsDirty = true;
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.I), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setNumOfSplits(3);
_pssmPass.setShadowMapSize(512);
updateText();
_quadsDirty = true;
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.J), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setUseSceneTexturing(!_pssmPass.isUseSceneTexturing());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.K), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setUseObjectCullFace(!_pssmPass.isUseObjectCullFace());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setEnabled(!_pssmPass.isEnabled());
updateText();
_quadsDirty = true;
}
}));
// Make sure all boundings are updated.
_root.acceptVisitor(new UpdateModelBoundVisitor(), false);
}
/**
* Setup debug quads to render pssm shadowmaps.
*/
private void updateQuadTextures(final Renderer r) {
if (!_quadsDirty) {
return;
}
_quadsDirty = false;
_pssmPass.reinit(r);
for (int i = 0; i < _pssmPass.getNumOfSplits(); i++) {
final TextureState screen = new TextureState();
final Texture2D copy = new Texture2D();
copy.setTextureKey(_pssmPass.getShadowMapTexture(i).getTextureKey());
screen.setTexture(copy);
_orthoQuad[i].setRenderState(screen);
_orthoQuad[i].getSceneHints().setCullHint(CullHint.Never);
_orthoQuad[i].updateGeometricState(0.0);
}
for (int i = _pssmPass.getNumOfSplits(); i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) {
_orthoQuad[i].getSceneHints().setCullHint(CullHint.Always);
}
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[0] Debug shader draw: " + _pssmPass.isDrawShaderDebug());
_exampleInfo[1].setText("[1] Update light: " + _updateLight);
_exampleInfo[2].setText("[2] Update main camera: " + _pssmPass.isUpdateMainCamera());
_exampleInfo[3].setText("[3] Debug draw: " + _pssmPass.isDrawDebug());
_exampleInfo[4].setText("[4/5] Number of splits: " + _pssmPass.getNumOfSplits());
_exampleInfo[5].setText("[6/7] Shadow map size: " + _pssmPass.getShadowMapSize());
_exampleInfo[6].setText("[8/9] Max shadow distance: " + _pssmPass.getMaxShadowDistance());
_exampleInfo[7].setText("[U] Setup 1 split of size 1024");
_exampleInfo[8].setText("[I] Setup 3 splits of size 512");
_exampleInfo[9].setText("[J] Use scene texturing: " + _pssmPass.isUseSceneTexturing());
_exampleInfo[10].setText("[K] Use object cull face: " + _pssmPass.isUseObjectCullFace());
_exampleInfo[11].setText("[SPACE] toggle PSSM pass: " + (_pssmPass.isEnabled() ? "enabled" : "disabled"));
}
/**
* Setup terrain.
*/
private void setupTerrain() {
final Box box = new Box("box", new Vector3(), 10000, 10, 10000);
box.setModelBound(new BoundingBox());
box.addController(new SpatialController<Box>() {
double timer = 0;
@Override
public void update(final double time, final Box caller) {
timer += time;
caller.setTranslation(Math.sin(timer) * 20.0, 0, Math.cos(timer) * 20.0);
}
});
_root.attachChild(box);
}
/**
* Setup occluders.
*/
private Node setupOccluders() {
final Node occluders = new Node("occs");
_root.attachChild(occluders);
for (int i = 0; i < 30; i++) {
final double w = Math.random() * 40 + 10;
final double y = Math.random() * 20 + 10;
final Box b = new Box("box", new Vector3(), w, y, w);
b.setModelBound(new BoundingBox());
final double x = Math.random() * 1000 - 500;
final double z = Math.random() * 1000 - 500;
b.setTranslation(new Vector3(x, y, z));
occluders.attachChild(b);
}
final Torus torusWithoutShadows = new Torus("torus", 32, 10, 15.0f, 20.0f);
torusWithoutShadows.setModelBound(new BoundingBox());
torusWithoutShadows.getSceneHints().setCastsShadows(false);
torusWithoutShadows.setTranslation(0, 50, -100);
occluders.attachChild(torusWithoutShadows);
final Torus torus = new Torus("torus", 64, 12, 10.0f, 15.0f);
torus.setModelBound(new BoundingBox());
occluders.attachChild(torus);
torus.addController(new SpatialController<Torus>() {
double timer = 0;
Matrix3 rotation = new Matrix3();
@Override
public void update(final double time, final Torus caller) {
timer += time;
caller.setTranslation(Math.sin(timer) * 40.0, Math.sin(timer) * 50.0 + 20.0, Math.cos(timer) * 40.0);
rotation.fromAngles(timer * 0.4, timer * 0.4, timer * 0.4);
caller.setRotation(rotation);
}
});
// Attach "billboard" with an alpha test.
occluders.attachChild(makeBillBoard());
return occluders;
}
private Spatial makeBillBoard() {
final Node billboard = new Node("bb");
billboard.getSceneHints().setRenderBucketType(RenderBucketType.Transparent);
final Quad q1 = new Quad("font block", 150, 200);
q1.setTranslation(0, 80, 0);
q1.setModelBound(new BoundingBox());
final CullState cs = new CullState();
cs.setCullFace(CullState.Face.None);
q1.setRenderState(cs);
billboard.attachChild(q1);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("fonts/OkasaSansSerif-35-medium-regular_00.png",
Texture.MinificationFilter.Trilinear, true));
billboard.setRenderState(ts);
final BlendState bs = new BlendState();
bs.setEnabled(true);
bs.setBlendEnabled(false);
bs.setTestEnabled(true);
bs.setTestFunction(TestFunction.GreaterThan);
bs.setReference(0.7f);
billboard.setRenderState(bs);
return billboard;
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleRampExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleRampExample.java index 5d48d82..643ebe1 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleRampExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleRampExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleSwarmExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleSwarmExample.java index b6c9172..9705a68 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleSwarmExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleSwarmExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleSystemExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleSystemExample.java index 7077921..2cddc0b 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleSystemExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ParticleSystemExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ProjectedGridExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ProjectedGridExample.java index 3ff01e1..0644573 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ProjectedGridExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ProjectedGridExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -96,30 +96,35 @@ public class ProjectedGridExample extends ExampleBase { _root.attachChild(projectedGrid); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { projectedGrid.setFreezeUpdate(!projectedGrid.isFreezeUpdate()); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { projectedGrid.setNrUpdateThreads(projectedGrid.getNrUpdateThreads() - 1); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { projectedGrid.setNrUpdateThreads(projectedGrid.getNrUpdateThreads() + 1); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { projectedGrid.setDrawDebug(!projectedGrid.isDrawDebug()); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { projectedGrid.setDrawDebug(true); animateExternalCamera = !animateExternalCamera; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ProjectedGridWaterExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ProjectedGridWaterExample.java index 0bb3aa5..835b751 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ProjectedGridWaterExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/ProjectedGridWaterExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.effect;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.effect.water.ProjectedGrid;
import com.ardor3d.extension.effect.water.WaterHeightGenerator;
import com.ardor3d.extension.effect.water.WaterNode;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Plane;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.ColorMaterial;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.controller.SpatialController;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Torus;
import com.ardor3d.scenegraph.visitor.UpdateModelBoundVisitor;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* A demonstration of the WaterNode and ProjectedGrid classes; which handles rendering of water effects with a projected
* grid.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.effect.ProjectedGridWaterExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/effect_ProjectedGridWaterExample.jpg", //
maxHeapMemory = 64)
public class ProjectedGridWaterExample extends ExampleBase {
/** The water instance taking care of the water rendering. */
private WaterNode waterNode;
/** The skybox. */
private Skybox skybox;
/** The ProjectedGrid used as geometry for the water. */
private ProjectedGrid projectedGrid;
/** The far plane. */
private final double farPlane = 10000.0;
/** Node containing debug quads for showing waternode render textures. */
private Node debugQuadsNode;
/** Flag for showing/hiding debug quads. */
private boolean showDebugQuads = true;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[3];
/**
* The main method.
*
* @param args
* the args
*/
public static void main(final String[] args) {
start(ProjectedGridWaterExample.class);
}
/**
* Update skybox location and waterQuad position.
*
* @param timer
* the timer
*/
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera cam = _canvas.getCanvasRenderer().getCamera();
skybox.setTranslation(cam.getLocation());
skybox.updateGeometricState(0.0f, true);
waterNode.update(timer.getTimePerFrame());
}
/**
* Render example.
*
* @param renderer
* the renderer
*/
@Override
protected void renderExample(final Renderer renderer) {
super.renderExample(renderer);
if (debugQuadsNode == null) {
createDebugQuads();
_root.attachChild(debugQuadsNode);
}
}
/**
* Initialize water node and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Projected Grid Water - Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(100, 50, 100));
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
45.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ (float) _canvas.getCanvasRenderer().getCamera().getHeight(), 1, farPlane);
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 0, 0), Vector3.UNIT_Y);
// Setup some standard states for the scene.
final CullState cullFrontFace = new CullState();
cullFrontFace.setEnabled(true);
cullFrontFace.setCullFace(CullState.Face.Back);
_root.setRenderState(cullFrontFace);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true));
_root.setRenderState(ts);
final MaterialState ms = new MaterialState();
ms.setColorMaterial(ColorMaterial.Diffuse);
_root.setRenderState(ms);
// Need to setup fog cause the water use it for various calculations.
setupFog();
// Collect everything we want reflected in the water under a node.
final Node reflectedNode = new Node("reflectNode");
reflectedNode.attachChild(createObjects());
buildSkyBox();
reflectedNode.attachChild(skybox);
_root.attachChild(reflectedNode);
final Camera cam = _canvas.getCanvasRenderer().getCamera();
// Create a new WaterNode with refraction enabled.
waterNode = new WaterNode(cam, 4, true, true);
waterNode.setClipBias(0.5f);
waterNode.setWaterMaxAmplitude(5.0f);
// Setup textures to use for the water.
waterNode.setNormalMapTextureString("images/water/normalmap3.dds");
waterNode.setDudvMapTextureString("images/water/dudvmap.png");
waterNode.setFallbackMapTextureString("images/water/water2.png");
waterNode.setFoamMapTextureString("images/water/oceanfoam.png");
// setting to default value just to show
waterNode.setWaterPlane(new Plane(new Vector3(0.0, 1.0, 0.0), 0.0));
// Create a ProjectedGrid to use as geometry for the water.
projectedGrid = new ProjectedGrid("ProjectedGrid", cam, 100, 70, 0.01f, new WaterHeightGenerator(), _timer);
// or implement your own waves like this(or in a separate class)...
// projectedGrid = new ProjectedGrid( "ProjectedGrid", cam, 50, 50,
// 0.01f, new HeightGenerator() {
// public float getHeight( float x, float z, float time ) {
// return
// FastMath.sin(x*0.05f+time*2.0f)+FastMath.cos(z*0.1f+time*4.0f)*2;
// }
// } );
projectedGrid.setNrUpdateThreads(Runtime.getRuntime().availableProcessors());
waterNode.attachChild(projectedGrid);
waterNode.addReflectedScene(reflectedNode);
waterNode.setSkybox(skybox);
_root.attachChild(waterNode);
// Setup textfields for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
// Register keyboard triggers for manipulating example
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
switchShowDebug();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
projectedGrid.setFreezeUpdate(!projectedGrid.isFreezeUpdate());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
projectedGrid.setNrUpdateThreads(projectedGrid.getNrUpdateThreads() - 1);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
projectedGrid.setNrUpdateThreads(projectedGrid.getNrUpdateThreads() + 1);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
waterNode.reloadShader();
}
}));
// Make sure all boundings are updated.
_root.acceptVisitor(new UpdateModelBoundVisitor(), false);
}
/**
* Setup fog.
*/
private void setupFog() {
final FogState fogState = new FogState();
fogState.setDensity(1.0f);
fogState.setEnabled(true);
fogState.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fogState.setEnd((float) farPlane);
fogState.setStart((float) farPlane / 10.0f);
fogState.setDensityFunction(FogState.DensityFunction.Linear);
fogState.setQuality(FogState.Quality.PerVertex);
_root.setRenderState(fogState);
}
/**
* Builds the sky box.
*/
private void buildSkyBox() {
skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
}
/**
* Creates the scene objects.
*
* @return the node containing the objects
*/
private Node createObjects() {
final Node objects = new Node("objects");
final Torus torus = new Torus("Torus", 50, 50, 8, 17);
torus.setTranslation(new Vector3(50, -5, 20));
TextureState ts = new TextureState();
torus.addController(new SpatialController<Torus>() {
private double timer = 0;
private final Matrix3 rotation = new Matrix3();
public void update(final double time, final Torus caller) {
timer += time * 0.5;
caller.setTranslation(Math.sin(timer) * 40.0, Math.sin(timer) * 40.0, Math.cos(timer) * 40.0);
rotation.fromAngles(timer * 0.5, timer * 0.5, timer * 0.5);
caller.setRotation(rotation);
}
});
Texture t0 = TextureManager.load("images/ardor3d_white_256.jpg",
Texture.MinificationFilter.BilinearNearestMipMap, true);
ts.setTexture(t0, 0);
ts.setEnabled(true);
torus.setRenderState(ts);
objects.attachChild(torus);
ts = new TextureState();
t0 = TextureManager
.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
t0.setWrap(Texture.WrapMode.Repeat);
ts.setTexture(t0);
Box box = new Box("box1", new Vector3(-10, -10, -10), new Vector3(10, 10, 10));
box.setTranslation(new Vector3(0, -7, 0));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box2", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(15, 10, 0));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box3", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(0, -10, 15));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box4", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(20, 0, 0));
box.setRenderState(ts);
objects.attachChild(box);
ts = new TextureState();
t0 = TextureManager
.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
t0.setWrap(Texture.WrapMode.Repeat);
ts.setTexture(t0);
box = new Box("box5", new Vector3(-50, -2, -50), new Vector3(50, 2, 50));
box.setTranslation(new Vector3(0, -15, 0));
box.setRenderState(ts);
box.setModelBound(new BoundingBox());
objects.attachChild(box);
return objects;
}
/**
* Switch show debug.
*/
private void switchShowDebug() {
showDebugQuads = !showDebugQuads;
if (showDebugQuads) {
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
} else {
debugQuadsNode.getSceneHints().setCullHint(CullHint.Always);
}
}
/**
* Creates the debug quads.
*/
private void createDebugQuads() {
debugQuadsNode = new Node("quadNode");
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
final double quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
Quad debugQuad = new Quad("reflectionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
TextureState ts = new TextureState();
ts.setTexture(waterNode.getTextureReflect());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 1.0, 1.0);
debugQuadsNode.attachChild(debugQuad);
if (waterNode.getTextureRefract() != null) {
debugQuad = new Quad("refractionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
ts = new TextureState();
ts.setTexture(waterNode.getTextureRefract());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 2.1, 1.0);
debugQuadsNode.attachChild(debugQuad);
}
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[SPACE] Show debug quads: " + showDebugQuads);
_exampleInfo[1].setText("[1/2] Number of update threads: " + projectedGrid.getNrUpdateThreads());
_exampleInfo[2].setText("[F] Freeze update: " + projectedGrid.isFreezeUpdate());
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.effect;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.effect.water.ProjectedGrid;
import com.ardor3d.extension.effect.water.WaterHeightGenerator;
import com.ardor3d.extension.effect.water.WaterNode;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Plane;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.ColorMaterial;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.controller.SpatialController;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Torus;
import com.ardor3d.scenegraph.visitor.UpdateModelBoundVisitor;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* A demonstration of the WaterNode and ProjectedGrid classes; which handles rendering of water effects with a projected
* grid.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.effect.ProjectedGridWaterExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/effect_ProjectedGridWaterExample.jpg", //
maxHeapMemory = 64)
public class ProjectedGridWaterExample extends ExampleBase {
/** The water instance taking care of the water rendering. */
private WaterNode waterNode;
/** The skybox. */
private Skybox skybox;
/** The ProjectedGrid used as geometry for the water. */
private ProjectedGrid projectedGrid;
/** The far plane. */
private final double farPlane = 10000.0;
/** Node containing debug quads for showing waternode render textures. */
private Node debugQuadsNode;
/** Flag for showing/hiding debug quads. */
private boolean showDebugQuads = true;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[3];
/**
* The main method.
*
* @param args
* the args
*/
public static void main(final String[] args) {
start(ProjectedGridWaterExample.class);
}
/**
* Update skybox location and waterQuad position.
*
* @param timer
* the timer
*/
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera cam = _canvas.getCanvasRenderer().getCamera();
skybox.setTranslation(cam.getLocation());
skybox.updateGeometricState(0.0f, true);
waterNode.update(timer.getTimePerFrame());
}
/**
* Render example.
*
* @param renderer
* the renderer
*/
@Override
protected void renderExample(final Renderer renderer) {
super.renderExample(renderer);
if (debugQuadsNode == null) {
createDebugQuads();
_root.attachChild(debugQuadsNode);
}
}
/**
* Initialize water node and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Projected Grid Water - Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(100, 50, 100));
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
45.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ (float) _canvas.getCanvasRenderer().getCamera().getHeight(), 1, farPlane);
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 0, 0), Vector3.UNIT_Y);
// Setup some standard states for the scene.
final CullState cullFrontFace = new CullState();
cullFrontFace.setEnabled(true);
cullFrontFace.setCullFace(CullState.Face.Back);
_root.setRenderState(cullFrontFace);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true));
_root.setRenderState(ts);
final MaterialState ms = new MaterialState();
ms.setColorMaterial(ColorMaterial.Diffuse);
_root.setRenderState(ms);
// Need to setup fog cause the water use it for various calculations.
setupFog();
// Collect everything we want reflected in the water under a node.
final Node reflectedNode = new Node("reflectNode");
reflectedNode.attachChild(createObjects());
buildSkyBox();
reflectedNode.attachChild(skybox);
_root.attachChild(reflectedNode);
final Camera cam = _canvas.getCanvasRenderer().getCamera();
// Create a new WaterNode with refraction enabled.
waterNode = new WaterNode(cam, 4, true, true);
waterNode.setClipBias(0.5f);
waterNode.setWaterMaxAmplitude(5.0f);
// Setup textures to use for the water.
waterNode.setNormalMapTextureString("images/water/normalmap3.dds");
waterNode.setDudvMapTextureString("images/water/dudvmap.png");
waterNode.setFallbackMapTextureString("images/water/water2.png");
waterNode.setFoamMapTextureString("images/water/oceanfoam.png");
// setting to default value just to show
waterNode.setWaterPlane(new Plane(new Vector3(0.0, 1.0, 0.0), 0.0));
// Create a ProjectedGrid to use as geometry for the water.
projectedGrid = new ProjectedGrid("ProjectedGrid", cam, 100, 70, 0.01f, new WaterHeightGenerator(), _timer);
// or implement your own waves like this(or in a separate class)...
// projectedGrid = new ProjectedGrid( "ProjectedGrid", cam, 50, 50,
// 0.01f, new HeightGenerator() {
// public float getHeight( float x, float z, float time ) {
// return
// FastMath.sin(x*0.05f+time*2.0f)+FastMath.cos(z*0.1f+time*4.0f)*2;
// }
// } );
projectedGrid.setNrUpdateThreads(Runtime.getRuntime().availableProcessors());
waterNode.attachChild(projectedGrid);
waterNode.addReflectedScene(reflectedNode);
waterNode.setSkybox(skybox);
_root.attachChild(waterNode);
// Setup textfields for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
// Register keyboard triggers for manipulating example
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
switchShowDebug();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
projectedGrid.setFreezeUpdate(!projectedGrid.isFreezeUpdate());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
projectedGrid.setNrUpdateThreads(projectedGrid.getNrUpdateThreads() - 1);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
projectedGrid.setNrUpdateThreads(projectedGrid.getNrUpdateThreads() + 1);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
waterNode.reloadShader();
}
}));
// Make sure all boundings are updated.
_root.acceptVisitor(new UpdateModelBoundVisitor(), false);
}
/**
* Setup fog.
*/
private void setupFog() {
final FogState fogState = new FogState();
fogState.setDensity(1.0f);
fogState.setEnabled(true);
fogState.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fogState.setEnd((float) farPlane);
fogState.setStart((float) farPlane / 10.0f);
fogState.setDensityFunction(FogState.DensityFunction.Linear);
fogState.setQuality(FogState.Quality.PerVertex);
_root.setRenderState(fogState);
}
/**
* Builds the sky box.
*/
private void buildSkyBox() {
skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
}
/**
* Creates the scene objects.
*
* @return the node containing the objects
*/
private Node createObjects() {
final Node objects = new Node("objects");
final Torus torus = new Torus("Torus", 50, 50, 8, 17);
torus.setTranslation(new Vector3(50, -5, 20));
TextureState ts = new TextureState();
torus.addController(new SpatialController<Torus>() {
private double timer = 0;
private final Matrix3 rotation = new Matrix3();
@Override
public void update(final double time, final Torus caller) {
timer += time * 0.5;
caller.setTranslation(Math.sin(timer) * 40.0, Math.sin(timer) * 40.0, Math.cos(timer) * 40.0);
rotation.fromAngles(timer * 0.5, timer * 0.5, timer * 0.5);
caller.setRotation(rotation);
}
});
Texture t0 = TextureManager.load("images/ardor3d_white_256.jpg",
Texture.MinificationFilter.BilinearNearestMipMap, true);
ts.setTexture(t0, 0);
ts.setEnabled(true);
torus.setRenderState(ts);
objects.attachChild(torus);
ts = new TextureState();
t0 = TextureManager
.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
t0.setWrap(Texture.WrapMode.Repeat);
ts.setTexture(t0);
Box box = new Box("box1", new Vector3(-10, -10, -10), new Vector3(10, 10, 10));
box.setTranslation(new Vector3(0, -7, 0));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box2", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(15, 10, 0));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box3", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(0, -10, 15));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box4", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(20, 0, 0));
box.setRenderState(ts);
objects.attachChild(box);
ts = new TextureState();
t0 = TextureManager
.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
t0.setWrap(Texture.WrapMode.Repeat);
ts.setTexture(t0);
box = new Box("box5", new Vector3(-50, -2, -50), new Vector3(50, 2, 50));
box.setTranslation(new Vector3(0, -15, 0));
box.setRenderState(ts);
box.setModelBound(new BoundingBox());
objects.attachChild(box);
return objects;
}
/**
* Switch show debug.
*/
private void switchShowDebug() {
showDebugQuads = !showDebugQuads;
if (showDebugQuads) {
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
} else {
debugQuadsNode.getSceneHints().setCullHint(CullHint.Always);
}
}
/**
* Creates the debug quads.
*/
private void createDebugQuads() {
debugQuadsNode = new Node("quadNode");
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
final double quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
Quad debugQuad = new Quad("reflectionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
TextureState ts = new TextureState();
ts.setTexture(waterNode.getTextureReflect());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 1.0, 1.0);
debugQuadsNode.attachChild(debugQuad);
if (waterNode.getTextureRefract() != null) {
debugQuad = new Quad("refractionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
ts = new TextureState();
ts.setTexture(waterNode.getTextureRefract());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 2.1, 1.0);
debugQuadsNode.attachChild(debugQuad);
}
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[SPACE] Show debug quads: " + showDebugQuads);
_exampleInfo[1].setText("[1/2] Number of update threads: " + projectedGrid.getNrUpdateThreads());
_exampleInfo[2].setText("[F] Freeze update: " + projectedGrid.isFreezeUpdate());
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/QuadImposterExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/QuadImposterExample.java index f0b214c..04daefd 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/QuadImposterExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/QuadImposterExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -101,6 +101,7 @@ public class QuadImposterExample extends ExampleBase { imposter2.attachChild(scene3); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showImposter = !showImposter; if (showImposter) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/TrailExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/TrailExample.java index bdcf643..58ce203 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/TrailExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/TrailExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -170,54 +170,63 @@ public class TrailExample extends ExampleBase { updateText(); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { trailMesh.setFacingMode(TrailMesh.FacingMode.Tangent); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { trailMesh.setFacingMode(TrailMesh.FacingMode.Billboard); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { trailMesh.setUpdateMode(TrailMesh.UpdateMode.Step); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { trailMesh.setUpdateMode(TrailMesh.UpdateMode.Interpolate); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { trailMesh.setUpdateSpeed(trailMesh.getUpdateSpeed() * 2.0f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { trailMesh.setUpdateSpeed(trailMesh.getUpdateSpeed() * 0.5f); updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { updateTrail = !updateTrail; updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { variableWidth = !variableWidth; updateText(); } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.E), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { trailMesh.resetPosition(sphere.getWorldTranslation()); updateText(); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/WaterExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/WaterExample.java index 8c93caf..10b769d 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/effect/WaterExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/effect/WaterExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.effect;
import java.nio.FloatBuffer;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.effect.water.WaterNode;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Plane;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.ColorMaterial;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.controller.SpatialController;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Torus;
import com.ardor3d.scenegraph.visitor.UpdateModelBoundVisitor;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* A demonstration of the WaterNode class; which handles rendering of a water effect on all of it's children.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.effect.WaterExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/effect_WaterExample.jpg", //
maxHeapMemory = 64)
public class WaterExample extends ExampleBase {
/** The water instance taking care of the water rendering. */
private WaterNode waterNode;
/** The skybox. */
private Skybox skybox;
/** The quad used as geometry for the water. */
private Quad waterQuad;
/** The far plane. */
private final double farPlane = 10000.0;
/** The texture scale to use for the water quad. */
private final double textureScale = 0.02;
/** Node containing debug quads for showing waternode render textures. */
private Node debugQuadsNode;
/** Flag for showing/hiding debug quads. */
private boolean showDebugQuads = true;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[1];
/**
* The main method.
*
* @param args
* the args
*/
public static void main(final String[] args) {
start(WaterExample.class);
}
/**
* Update skybox location and waterQuad position.
*
* @param timer
* the timer
*/
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera cam = _canvas.getCanvasRenderer().getCamera();
skybox.setTranslation(cam.getLocation());
skybox.updateGeometricState(0.0f, true);
final Vector3 transVec = new Vector3(cam.getLocation().getX(), waterNode.getWaterHeight(), cam.getLocation()
.getZ());
setTextureCoords(0, transVec.getX(), -transVec.getZ(), textureScale);
// vertex coords
setVertexCoords(transVec.getX(), transVec.getY(), transVec.getZ());
waterNode.update(timer.getTimePerFrame());
}
/**
* Render example.
*
* @param renderer
* the renderer
*/
@Override
protected void renderExample(final Renderer renderer) {
super.renderExample(renderer);
if (debugQuadsNode == null) {
createDebugQuads();
_root.attachChild(debugQuadsNode);
}
}
/**
* Initialize water node and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Quad Water - Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(100, 50, 100));
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
45.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ (float) _canvas.getCanvasRenderer().getCamera().getHeight(), 1, farPlane);
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 0, 0), Vector3.UNIT_Y);
// Setup some standard states for the scene.
final CullState cullFrontFace = new CullState();
cullFrontFace.setEnabled(true);
cullFrontFace.setCullFace(CullState.Face.Back);
_root.setRenderState(cullFrontFace);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true));
_root.setRenderState(ts);
final MaterialState ms = new MaterialState();
ms.setColorMaterial(ColorMaterial.Diffuse);
_root.setRenderState(ms);
// Need to setup fog cause the water use it for various calculations.
setupFog();
// Collect everything we want reflected in the water under a node.
final Node reflectedNode = new Node("reflectNode");
reflectedNode.attachChild(createObjects());
buildSkyBox();
reflectedNode.attachChild(skybox);
_root.attachChild(reflectedNode);
final Camera cam = _canvas.getCanvasRenderer().getCamera();
// Create a new WaterNode with refraction enabled.
waterNode = new WaterNode(cam, 4, false, true);
// Setup textures to use for the water.
waterNode.setNormalMapTextureString("images/water/normalmap3.dds");
waterNode.setDudvMapTextureString("images/water/dudvmap.png");
waterNode.setFallbackMapTextureString("images/water/water2.png");
// setting to default value just to show
waterNode.setWaterPlane(new Plane(new Vector3(0.0, 1.0, 0.0), 0.0));
// Create a quad to use as geometry for the water.
waterQuad = new Quad("waterQuad", 1, 1);
// Hack the quad normals to point up in the y-axis. Since we are manipulating the vertices as
// we move this is more convenient than rotating the quad.
final FloatBuffer normBuf = waterQuad.getMeshData().getNormalBuffer();
normBuf.clear();
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
waterNode.attachChild(waterQuad);
waterNode.addReflectedScene(reflectedNode);
waterNode.setSkybox(skybox);
_root.attachChild(waterNode);
// Setyp textfields for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
// Register keyboard triggers for manipulating example
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
switchShowDebug();
updateText();
}
}));
// Make sure all boundings are updated.
_root.acceptVisitor(new UpdateModelBoundVisitor(), false);
}
/**
* Sets the vertex coords of the quad.
*
* @param x
* the x
* @param y
* the y
* @param z
* the z
*/
private void setVertexCoords(final double x, final double y, final double z) {
final FloatBuffer vertBuf = waterQuad.getMeshData().getVertexBuffer();
vertBuf.clear();
vertBuf.put((float) (x - farPlane)).put((float) y).put((float) (z - farPlane));
vertBuf.put((float) (x - farPlane)).put((float) y).put((float) (z + farPlane));
vertBuf.put((float) (x + farPlane)).put((float) y).put((float) (z + farPlane));
vertBuf.put((float) (x + farPlane)).put((float) y).put((float) (z - farPlane));
}
/**
* Sets the texture coords of the quad.
*
* @param buffer
* the buffer
* @param x
* the x
* @param y
* the y
* @param textureScale
* the texture scale
*/
private void setTextureCoords(final int buffer, double x, double y, double textureScale) {
x *= textureScale * 0.5f;
y *= textureScale * 0.5f;
textureScale = farPlane * textureScale;
FloatBuffer texBuf;
texBuf = waterQuad.getMeshData().getTextureBuffer(buffer);
texBuf.clear();
texBuf.put((float) x).put((float) (textureScale + y));
texBuf.put((float) x).put((float) y);
texBuf.put((float) (textureScale + x)).put((float) y);
texBuf.put((float) (textureScale + x)).put((float) (textureScale + y));
}
/**
* Setup fog.
*/
private void setupFog() {
final FogState fogState = new FogState();
fogState.setDensity(1.0f);
fogState.setEnabled(true);
fogState.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fogState.setEnd((float) farPlane);
fogState.setStart((float) farPlane / 10.0f);
fogState.setDensityFunction(FogState.DensityFunction.Linear);
fogState.setQuality(FogState.Quality.PerVertex);
_root.setRenderState(fogState);
}
/**
* Builds the sky box.
*/
private void buildSkyBox() {
skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
}
/**
* Creates the scene objects.
*
* @return the node containing the objects
*/
private Node createObjects() {
final Node objects = new Node("objects");
final Torus torus = new Torus("Torus", 50, 50, 8, 17);
torus.setTranslation(new Vector3(50, -5, 20));
TextureState ts = new TextureState();
torus.addController(new SpatialController<Torus>() {
private double timer = 0;
private final Matrix3 rotation = new Matrix3();
public void update(final double time, final Torus caller) {
timer += time * 0.5;
caller.setTranslation(Math.sin(timer) * 40.0, Math.sin(timer) * 40.0, Math.cos(timer) * 40.0);
rotation.fromAngles(timer * 0.5, timer * 0.5, timer * 0.5);
caller.setRotation(rotation);
}
});
Texture t0 = TextureManager.load("images/ardor3d_white_256.jpg",
Texture.MinificationFilter.BilinearNearestMipMap, true);
ts.setTexture(t0, 0);
ts.setEnabled(true);
torus.setRenderState(ts);
objects.attachChild(torus);
ts = new TextureState();
t0 = TextureManager
.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
t0.setWrap(Texture.WrapMode.Repeat);
ts.setTexture(t0);
Box box = new Box("box1", new Vector3(-10, -10, -10), new Vector3(10, 10, 10));
box.setTranslation(new Vector3(0, -7, 0));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box2", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(15, 10, 0));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box3", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(0, -10, 15));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box4", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(20, 0, 0));
box.setRenderState(ts);
objects.attachChild(box);
ts = new TextureState();
t0 = TextureManager
.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
t0.setWrap(Texture.WrapMode.Repeat);
ts.setTexture(t0);
box = new Box("box5", new Vector3(-50, -2, -50), new Vector3(50, 2, 50));
box.setTranslation(new Vector3(0, -15, 0));
box.setRenderState(ts);
box.setModelBound(new BoundingBox());
objects.attachChild(box);
return objects;
}
/**
* Switch show debug.
*/
private void switchShowDebug() {
showDebugQuads = !showDebugQuads;
if (showDebugQuads) {
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
} else {
debugQuadsNode.getSceneHints().setCullHint(CullHint.Always);
}
}
/**
* Creates the debug quads.
*/
private void createDebugQuads() {
debugQuadsNode = new Node("quadNode");
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
final double quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
Quad debugQuad = new Quad("reflectionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
TextureState ts = new TextureState();
ts.setTexture(waterNode.getTextureReflect());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 1.0, 1.0);
debugQuadsNode.attachChild(debugQuad);
if (waterNode.getTextureRefract() != null) {
debugQuad = new Quad("refractionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
ts = new TextureState();
ts.setTexture(waterNode.getTextureRefract());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 2.1, 1.0);
debugQuadsNode.attachChild(debugQuad);
}
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[SPACE] Show debug quads: " + showDebugQuads);
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.effect;
import java.nio.FloatBuffer;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.effect.water.WaterNode;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Plane;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.ColorMaterial;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.controller.SpatialController;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Torus;
import com.ardor3d.scenegraph.visitor.UpdateModelBoundVisitor;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* A demonstration of the WaterNode class; which handles rendering of a water effect on all of it's children.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.effect.WaterExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/effect_WaterExample.jpg", //
maxHeapMemory = 64)
public class WaterExample extends ExampleBase {
/** The water instance taking care of the water rendering. */
private WaterNode waterNode;
/** The skybox. */
private Skybox skybox;
/** The quad used as geometry for the water. */
private Quad waterQuad;
/** The far plane. */
private final double farPlane = 10000.0;
/** The texture scale to use for the water quad. */
private final double textureScale = 0.02;
/** Node containing debug quads for showing waternode render textures. */
private Node debugQuadsNode;
/** Flag for showing/hiding debug quads. */
private boolean showDebugQuads = true;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[1];
/**
* The main method.
*
* @param args
* the args
*/
public static void main(final String[] args) {
start(WaterExample.class);
}
/**
* Update skybox location and waterQuad position.
*
* @param timer
* the timer
*/
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera cam = _canvas.getCanvasRenderer().getCamera();
skybox.setTranslation(cam.getLocation());
skybox.updateGeometricState(0.0f, true);
final Vector3 transVec = new Vector3(cam.getLocation().getX(), waterNode.getWaterHeight(), cam.getLocation()
.getZ());
setTextureCoords(0, transVec.getX(), -transVec.getZ(), textureScale);
// vertex coords
setVertexCoords(transVec.getX(), transVec.getY(), transVec.getZ());
waterNode.update(timer.getTimePerFrame());
}
/**
* Render example.
*
* @param renderer
* the renderer
*/
@Override
protected void renderExample(final Renderer renderer) {
super.renderExample(renderer);
if (debugQuadsNode == null) {
createDebugQuads();
_root.attachChild(debugQuadsNode);
}
}
/**
* Initialize water node and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Quad Water - Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(100, 50, 100));
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
45.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ (float) _canvas.getCanvasRenderer().getCamera().getHeight(), 1, farPlane);
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 0, 0), Vector3.UNIT_Y);
// Setup some standard states for the scene.
final CullState cullFrontFace = new CullState();
cullFrontFace.setEnabled(true);
cullFrontFace.setCullFace(CullState.Face.Back);
_root.setRenderState(cullFrontFace);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.Trilinear, true));
_root.setRenderState(ts);
final MaterialState ms = new MaterialState();
ms.setColorMaterial(ColorMaterial.Diffuse);
_root.setRenderState(ms);
// Need to setup fog cause the water use it for various calculations.
setupFog();
// Collect everything we want reflected in the water under a node.
final Node reflectedNode = new Node("reflectNode");
reflectedNode.attachChild(createObjects());
buildSkyBox();
reflectedNode.attachChild(skybox);
_root.attachChild(reflectedNode);
final Camera cam = _canvas.getCanvasRenderer().getCamera();
// Create a new WaterNode with refraction enabled.
waterNode = new WaterNode(cam, 4, false, true);
// Setup textures to use for the water.
waterNode.setNormalMapTextureString("images/water/normalmap3.dds");
waterNode.setDudvMapTextureString("images/water/dudvmap.png");
waterNode.setFallbackMapTextureString("images/water/water2.png");
// setting to default value just to show
waterNode.setWaterPlane(new Plane(new Vector3(0.0, 1.0, 0.0), 0.0));
// Create a quad to use as geometry for the water.
waterQuad = new Quad("waterQuad", 1, 1);
// Hack the quad normals to point up in the y-axis. Since we are manipulating the vertices as
// we move this is more convenient than rotating the quad.
final FloatBuffer normBuf = waterQuad.getMeshData().getNormalBuffer();
normBuf.clear();
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
waterNode.attachChild(waterQuad);
waterNode.addReflectedScene(reflectedNode);
waterNode.setSkybox(skybox);
_root.attachChild(waterNode);
// Setyp textfields for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
// Register keyboard triggers for manipulating example
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
switchShowDebug();
updateText();
}
}));
// Make sure all boundings are updated.
_root.acceptVisitor(new UpdateModelBoundVisitor(), false);
}
/**
* Sets the vertex coords of the quad.
*
* @param x
* the x
* @param y
* the y
* @param z
* the z
*/
private void setVertexCoords(final double x, final double y, final double z) {
final FloatBuffer vertBuf = waterQuad.getMeshData().getVertexBuffer();
vertBuf.clear();
vertBuf.put((float) (x - farPlane)).put((float) y).put((float) (z - farPlane));
vertBuf.put((float) (x - farPlane)).put((float) y).put((float) (z + farPlane));
vertBuf.put((float) (x + farPlane)).put((float) y).put((float) (z + farPlane));
vertBuf.put((float) (x + farPlane)).put((float) y).put((float) (z - farPlane));
}
/**
* Sets the texture coords of the quad.
*
* @param buffer
* the buffer
* @param x
* the x
* @param y
* the y
* @param textureScale
* the texture scale
*/
private void setTextureCoords(final int buffer, double x, double y, double textureScale) {
x *= textureScale * 0.5f;
y *= textureScale * 0.5f;
textureScale = farPlane * textureScale;
FloatBuffer texBuf;
texBuf = waterQuad.getMeshData().getTextureBuffer(buffer);
texBuf.clear();
texBuf.put((float) x).put((float) (textureScale + y));
texBuf.put((float) x).put((float) y);
texBuf.put((float) (textureScale + x)).put((float) y);
texBuf.put((float) (textureScale + x)).put((float) (textureScale + y));
}
/**
* Setup fog.
*/
private void setupFog() {
final FogState fogState = new FogState();
fogState.setDensity(1.0f);
fogState.setEnabled(true);
fogState.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fogState.setEnd((float) farPlane);
fogState.setStart((float) farPlane / 10.0f);
fogState.setDensityFunction(FogState.DensityFunction.Linear);
fogState.setQuality(FogState.Quality.PerVertex);
_root.setRenderState(fogState);
}
/**
* Builds the sky box.
*/
private void buildSkyBox() {
skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
}
/**
* Creates the scene objects.
*
* @return the node containing the objects
*/
private Node createObjects() {
final Node objects = new Node("objects");
final Torus torus = new Torus("Torus", 50, 50, 8, 17);
torus.setTranslation(new Vector3(50, -5, 20));
TextureState ts = new TextureState();
torus.addController(new SpatialController<Torus>() {
private double timer = 0;
private final Matrix3 rotation = new Matrix3();
@Override
public void update(final double time, final Torus caller) {
timer += time * 0.5;
caller.setTranslation(Math.sin(timer) * 40.0, Math.sin(timer) * 40.0, Math.cos(timer) * 40.0);
rotation.fromAngles(timer * 0.5, timer * 0.5, timer * 0.5);
caller.setRotation(rotation);
}
});
Texture t0 = TextureManager.load("images/ardor3d_white_256.jpg",
Texture.MinificationFilter.BilinearNearestMipMap, true);
ts.setTexture(t0, 0);
ts.setEnabled(true);
torus.setRenderState(ts);
objects.attachChild(torus);
ts = new TextureState();
t0 = TextureManager
.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
t0.setWrap(Texture.WrapMode.Repeat);
ts.setTexture(t0);
Box box = new Box("box1", new Vector3(-10, -10, -10), new Vector3(10, 10, 10));
box.setTranslation(new Vector3(0, -7, 0));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box2", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(15, 10, 0));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box3", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(0, -10, 15));
box.setRenderState(ts);
objects.attachChild(box);
box = new Box("box4", new Vector3(-5, -5, -5), new Vector3(5, 5, 5));
box.setTranslation(new Vector3(20, 0, 0));
box.setRenderState(ts);
objects.attachChild(box);
ts = new TextureState();
t0 = TextureManager
.load("images/ardor3d_white_256.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
t0.setWrap(Texture.WrapMode.Repeat);
ts.setTexture(t0);
box = new Box("box5", new Vector3(-50, -2, -50), new Vector3(50, 2, 50));
box.setTranslation(new Vector3(0, -15, 0));
box.setRenderState(ts);
box.setModelBound(new BoundingBox());
objects.attachChild(box);
return objects;
}
/**
* Switch show debug.
*/
private void switchShowDebug() {
showDebugQuads = !showDebugQuads;
if (showDebugQuads) {
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
} else {
debugQuadsNode.getSceneHints().setCullHint(CullHint.Always);
}
}
/**
* Creates the debug quads.
*/
private void createDebugQuads() {
debugQuadsNode = new Node("quadNode");
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
final double quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
Quad debugQuad = new Quad("reflectionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
TextureState ts = new TextureState();
ts.setTexture(waterNode.getTextureReflect());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 1.0, 1.0);
debugQuadsNode.attachChild(debugQuad);
if (waterNode.getTextureRefract() != null) {
debugQuad = new Quad("refractionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
ts = new TextureState();
ts.setTexture(waterNode.getTextureRefract());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 2.1, 1.0);
debugQuadsNode.attachChild(debugQuad);
}
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[SPACE] Show debug quads: " + showDebugQuads);
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/interact/InteractExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/interact/InteractExample.java index 0fcbf1e..da38966 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/interact/InteractExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/interact/InteractExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/interact/TerrainHeightFilter.java b/ardor3d-examples/src/main/java/com/ardor3d/example/interact/TerrainHeightFilter.java index 18621d5..26f57f4 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/interact/TerrainHeightFilter.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/interact/TerrainHeightFilter.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/interact/TerrainInteractExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/interact/TerrainInteractExample.java index 668112d..601d890 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/interact/TerrainInteractExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/interact/TerrainInteractExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.interact;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.interact.InteractManager;
import com.ardor3d.extension.interact.widget.CompoundInteractWidget;
import com.ardor3d.extension.interact.widget.InteractMatrix;
import com.ardor3d.extension.interact.widget.MovePlanarWidget.MovePlane;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.heightmap.MidPointHeightMapGenerator;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Texture.MinificationFilter;
import com.ardor3d.image.Texture2D;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.shape.PQTorus;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing interact widgets with the Geometry Clipmap Terrain system. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.interact.TerrainInteractExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/interact_TerrainInteractExample.jpg", //
maxHeapMemory = 128)
public class TerrainInteractExample extends ExampleBase {
private final float farPlane = 3000.0f;
private Terrain terrain;
private InteractManager manager;
public static void main(final String[] args) {
ExampleBase.start(TerrainInteractExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
manager.update(timer);
}
@Override
protected void updateLogicalLayer(final ReadOnlyTimer timer) {
manager.getLogicalLayer().checkTriggers(timer.getTimePerFrame());
}
@Override
protected void renderExample(final Renderer renderer) {
super.renderExample(renderer);
manager.render(renderer);
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(400, 220, 715));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(430, 200, 730), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(500);
setupDefaultStates();
try {
final int SIZE = 2048;
final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.6f);
raw.setHeightRange(0.2f);
final float[] heightMap = raw.getHeightData();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 500, 1));
terrain = new TerrainBuilder(terrainDataProvider, _canvas.getCanvasRenderer().getCamera())
.setShowDebugPanels(false).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
addControls();
// Add something to move around
final PQTorus obj = new PQTorus("obj", 4, 3, 1.5, .5, 128, 8);
obj.setScale(10);
obj.updateModelBound();
_root.attachChild(obj);
_root.updateGeometricState(0);
try {
Thread.sleep(500);
} catch (final InterruptedException e) {
}
obj.setTranslation(630, terrain.getHeightAt(630, 830) + 20, 830);
manager.setSpatialTarget(obj);
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(ColorRGBA.GRAY);
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
private void addControls() {
// create our manager
manager = new InteractManager();
manager.setupInput(_canvas, _physicalLayer, _logicalLayer);
// final add our widget
final CompoundInteractWidget widget = new CompoundInteractWidget()
.withMoveXAxis(new ColorRGBA(1, 0, 0, .65f), 1.2, .15, .5, .2)
.withMoveZAxis(new ColorRGBA(0, 0, 1, .65f), 1.2, .15, .5, .2) //
.withRotateYAxis() //
.withPlanarHandle(MovePlane.XZ, new ColorRGBA(1, 0, 1, .65f)) //
.withRingTexture((Texture2D) TextureManager.load("images/tick.png", MinificationFilter.Trilinear, true));
// widget.getHandle().setRenderState(_lightState);
manager.addWidget(widget);
manager.setActiveWidget(widget);
// add toggle for matrix mode on widget
manager.getLogicalLayer().registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
widget.setInteractMatrix(widget.getInteractMatrix() == InteractMatrix.World ? InteractMatrix.Local
: InteractMatrix.World);
widget.targetDataUpdated(manager);
}
}));
// add a filter
manager.addFilter(new TerrainHeightFilter(terrain, 20));
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.interact;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.interact.InteractManager;
import com.ardor3d.extension.interact.widget.CompoundInteractWidget;
import com.ardor3d.extension.interact.widget.InteractMatrix;
import com.ardor3d.extension.interact.widget.MovePlanarWidget.MovePlane;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.heightmap.MidPointHeightMapGenerator;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Texture.MinificationFilter;
import com.ardor3d.image.Texture2D;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.shape.PQTorus;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing interact widgets with the Geometry Clipmap Terrain system. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.interact.TerrainInteractExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/interact_TerrainInteractExample.jpg", //
maxHeapMemory = 128)
public class TerrainInteractExample extends ExampleBase {
private final float farPlane = 3000.0f;
private Terrain terrain;
private InteractManager manager;
public static void main(final String[] args) {
ExampleBase.start(TerrainInteractExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
manager.update(timer);
}
@Override
protected void updateLogicalLayer(final ReadOnlyTimer timer) {
manager.getLogicalLayer().checkTriggers(timer.getTimePerFrame());
}
@Override
protected void renderExample(final Renderer renderer) {
super.renderExample(renderer);
manager.render(renderer);
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(400, 220, 715));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(430, 200, 730), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(500);
setupDefaultStates();
try {
final int SIZE = 2048;
final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.6f);
raw.setHeightRange(0.2f);
final float[] heightMap = raw.getHeightData();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 500, 1));
terrain = new TerrainBuilder(terrainDataProvider, _canvas.getCanvasRenderer().getCamera())
.setShowDebugPanels(false).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
addControls();
// Add something to move around
final PQTorus obj = new PQTorus("obj", 4, 3, 1.5, .5, 128, 8);
obj.setScale(10);
obj.updateModelBound();
_root.attachChild(obj);
_root.updateGeometricState(0);
try {
Thread.sleep(500);
} catch (final InterruptedException e) {
}
obj.setTranslation(630, terrain.getHeightAt(630, 830) + 20, 830);
manager.setSpatialTarget(obj);
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(ColorRGBA.GRAY);
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
private void addControls() {
// create our manager
manager = new InteractManager();
manager.setupInput(_canvas, _physicalLayer, _logicalLayer);
// final add our widget
final CompoundInteractWidget widget = new CompoundInteractWidget()
.withMoveXAxis(new ColorRGBA(1, 0, 0, .65f), 1.2, .15, .5, .2)
.withMoveZAxis(new ColorRGBA(0, 0, 1, .65f), 1.2, .15, .5, .2) //
.withRotateYAxis() //
.withPlanarHandle(MovePlane.XZ, new ColorRGBA(1, 0, 1, .65f)) //
.withRingTexture((Texture2D) TextureManager.load("images/tick.png", MinificationFilter.Trilinear, true));
// widget.getHandle().setRenderState(_lightState);
manager.addWidget(widget);
manager.setActiveWidget(widget);
// add toggle for matrix mode on widget
manager.getLogicalLayer().registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
widget.setInteractMatrix(widget.getInteractMatrix() == InteractMatrix.World ? InteractMatrix.Local
: InteractMatrix.World);
widget.targetDataUpdated(manager);
}
}));
// add a filter
manager.addFilter(new TerrainHeightFilter(terrain, 20));
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/CurveInterpolationControllerExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/CurveInterpolationControllerExample.java index ca54564..2fd290e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/CurveInterpolationControllerExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/CurveInterpolationControllerExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/DefaultColorInterpolationControllerExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/DefaultColorInterpolationControllerExample.java index 2bd2a97..a673735 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/DefaultColorInterpolationControllerExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/DefaultColorInterpolationControllerExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/InterpolationControllerBase.java b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/InterpolationControllerBase.java index 78ea46e..fc8c7e2 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/InterpolationControllerBase.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/InterpolationControllerBase.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -77,6 +77,7 @@ public abstract class InterpolationControllerBase<C extends InterpolationControl // Add a trigger to change the repeat type on the controller _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { switch (controller.getRepeatType()) { case CLAMP: @@ -95,6 +96,7 @@ public abstract class InterpolationControllerBase<C extends InterpolationControl // Add a slow down command _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.LBRACKET), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { controller.setSpeed(getNewSpeed(false, controller)); speedText.setText(getSpeedText(controller)); @@ -103,6 +105,7 @@ public abstract class InterpolationControllerBase<C extends InterpolationControl // Add a speed up command _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.RBRACKET), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { controller.setSpeed(getNewSpeed(true, controller)); speedText.setText(getSpeedText(controller)); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/LinearVector3InterpolationControllerExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/LinearVector3InterpolationControllerExample.java index b907305..5c9682e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/LinearVector3InterpolationControllerExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/LinearVector3InterpolationControllerExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/QuaternionInterpolationControllerExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/QuaternionInterpolationControllerExample.java index 68f86cf..18f8ee3 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/QuaternionInterpolationControllerExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/interpolation/QuaternionInterpolationControllerExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationBlinnPhongExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationBlinnPhongExample.java index f6b1889..11401c7 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationBlinnPhongExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationBlinnPhongExample.java @@ -131,6 +131,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { final BasicText t6 = createTextLabel("Text5", "[Y] Enable Light Motion.", 5); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { useDiffuseMap = !useDiffuseMap; gpuShader.setUniform("flags", useNormalMap, useDiffuseMap, useSpecularMap, false); @@ -143,6 +144,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NUMPADADD), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { if (quantizationFactor > 1) { quantizationFactor /= 2f; @@ -153,6 +155,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NUMPADSUBTRACT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { if (quantizationFactor < 512) { quantizationFactor *= 2f; @@ -163,6 +166,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.Y), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { updateLight = !updateLight; if (updateLight) { @@ -174,6 +178,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { useSpecularMap = !useSpecularMap; gpuShader.setUniform("flags", useNormalMap, useDiffuseMap, useSpecularMap, false); @@ -186,6 +191,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { useNormalMap = !useNormalMap; gpuShader.setUniform("flags", useNormalMap, useDiffuseMap, useSpecularMap, false); @@ -198,6 +204,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.K), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showSkeleton = !showSkeleton; if (showSkeleton) { @@ -209,6 +216,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.M), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showMesh = !showMesh; colladaNode.getSceneHints().setCullHint(showMesh ? CullHint.Dynamic : CullHint.Always); @@ -285,6 +293,7 @@ public class AnimationBlinnPhongExample extends ExampleBase { gpuShader.setUniform("specularMap", 2); colladaNode.acceptVisitor(new Visitor() { + @Override public void visit(final Spatial spatial) { if (spatial instanceof SkinnedMesh) { final SkinnedMesh skinnedMesh = (SkinnedMesh) spatial; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationCopyExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationCopyExample.java index 6ff67d7..055c242 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationCopyExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationCopyExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -166,6 +166,7 @@ public class AnimationCopyExample extends ExampleBase { runWalkButton.addActionListener(new ActionListener() { boolean walk = true; + @Override public void actionPerformed(final ActionEvent event) { if (!walk) { if (manager.getBaseAnimationLayer().doTransition("walk")) { @@ -186,6 +187,7 @@ public class AnimationCopyExample extends ExampleBase { punchButton .setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, runWalkButton, Alignment.BOTTOM_LEFT, 0, -5)); punchButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { manager.findAnimationLayer("punch").setCurrentState("punch_right", true); punchButton.setEnabled(false); @@ -198,6 +200,7 @@ public class AnimationCopyExample extends ExampleBase { headCheck.setSelected(true); headCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { manager.getValuesStore().put("head_blend", headCheck.isSelected() ? 1.0 : 0.0); } @@ -209,6 +212,7 @@ public class AnimationCopyExample extends ExampleBase { .setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, headCheck, Alignment.BOTTOM_LEFT, 0, -5)); gpuSkinningCheck.setSelected(false); gpuSkinningCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { _root.acceptVisitor(new Visitor() { @Override @@ -234,6 +238,7 @@ public class AnimationCopyExample extends ExampleBase { vboCheck.setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, gpuSkinningCheck, Alignment.BOTTOM_LEFT, 0, -5)); vboCheck.setSelected(false); vboCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { skNode.getSceneHints().setDataMode(vboCheck.isSelected() ? DataMode.VBO : DataMode.Arrays); gpuShader.setUseAttributeVBO(vboCheck.isSelected()); @@ -247,6 +252,7 @@ public class AnimationCopyExample extends ExampleBase { skeletonCheck.setSelected(showSkeleton); skeletonCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { showSkeleton = skeletonCheck.isSelected(); boneLabelCheck.setEnabled(showSkeleton); @@ -260,6 +266,7 @@ public class AnimationCopyExample extends ExampleBase { boneLabelCheck.setEnabled(showSkeleton); boneLabelCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { showJointLabels = boneLabelCheck.isSelected(); } @@ -373,6 +380,7 @@ public class AnimationCopyExample extends ExampleBase { // Add a call back to load clips. final InputStore input = new InputStore(); input.getClips().setMissCallback(new MissingCallback<String, AnimationClip>() { + @Override public AnimationClip getValue(final String key) { try { final ColladaStorage storage1 = colladaImporter.load("collada/skeleton/" + key + ".dae"); @@ -404,6 +412,7 @@ public class AnimationCopyExample extends ExampleBase { _root.addController(new SpatialController<Node>() { private final Quaternion headRotation = new Quaternion(); + @Override public void update(final double time, final Node caller) { // update the head's position if (headCheck != null && headCheck.isSelected()) { @@ -425,6 +434,7 @@ public class AnimationCopyExample extends ExampleBase { // add callback for our UI manager.findClipInstance("skeleton.punch").addAnimationListener(new AnimationListener() { + @Override public void animationFinished(final AnimationClipInstance source) { punchButton.setEnabled(true); } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationDemoExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationDemoExample.java index 746f0a1..43bc87c 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationDemoExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationDemoExample.java @@ -1,9 +1,9 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * - * Ardor3D is free software: you can redistribute it and/or modify it + * Ardor3D is free software: you can redistribute it and/or modify it * under the terms of its license which may be found in the accompanying * LICENSE file or at <http://www.ardor3d.com/LICENSE>. */ @@ -11,6 +11,9 @@ package com.ardor3d.example.pipeline; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; @@ -51,24 +54,22 @@ import com.ardor3d.util.geom.MeshCombiner; import com.ardor3d.util.resource.ResourceLocatorTool; import com.ardor3d.util.resource.ResourceSource; import com.ardor3d.util.resource.URLResourceSource; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; /** * Illustrates loading several animations from Collada and arranging them in an animation state machine. */ @Purpose(htmlDescriptionKey = "com.ardor3d.example.pipeline.AnimationDemoExample", // -thumbnailPath = "com/ardor3d/example/media/thumbnails/pipeline_AnimationDemoExample.jpg", // -maxHeapMemory = 64) + thumbnailPath = "com/ardor3d/example/media/thumbnails/pipeline_AnimationDemoExample.jpg", // + maxHeapMemory = 64) public class AnimationDemoExample extends ExampleBase { private static final long MIN_STATE_TIME = 5000; static AnimationDemoExample instance; - private final List<AnimationManager> managers = Lists.newArrayList(); - private final List<AnimationInfo> animInfo = Lists.newArrayList(); - private final Map<SkeletonPose, SkinnedMesh> poseToMesh = Maps.newIdentityHashMap(); + private final List<AnimationManager> managers = new ArrayList<>(); + private final List<AnimationInfo> animInfo = new ArrayList<>(); + private final Map<SkeletonPose, SkinnedMesh> poseToMesh = new IdentityHashMap<>(); public static void main(final String[] args) { ExampleBase.start(AnimationDemoExample.class); @@ -147,8 +148,7 @@ public class AnimationDemoExample extends ExampleBase { try { gpuShader.setVertexShader(ResourceLocatorTool.getClassPathResourceAsStream(AnimationDemoExample.class, "com/ardor3d/extension/animation/skeletal/skinning_gpu_texture.vert")); - gpuShader.setFragmentShader(ResourceLocatorTool.getClassPathResourceAsStream( - AnimationDemoExample.class, + gpuShader.setFragmentShader(ResourceLocatorTool.getClassPathResourceAsStream(AnimationDemoExample.class, "com/ardor3d/extension/animation/skeletal/skinning_gpu_texture.frag")); gpuShader.setUniform("texture", 0); @@ -196,7 +196,7 @@ public class AnimationDemoExample extends ExampleBase { return skeleton; } - private final Map<String, AnimationClip> animationStore = Maps.newHashMap(); + private final Map<String, AnimationClip> animationStore = new HashMap<>(); private AnimationManager createAnimationManager(final SkeletonPose pose) { // Make our manager @@ -209,6 +209,7 @@ public class AnimationDemoExample extends ExampleBase { // Add a call back to load clips. final InputStore input = new InputStore(); input.getClips().setMissCallback(new MissingCallback<String, AnimationClip>() { + @Override public AnimationClip getValue(final String key) { if (!animationStore.containsKey(key)) { try { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationStateExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationStateExample.java index 44b3407..b9120a4 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationStateExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/AnimationStateExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -161,6 +161,7 @@ public class AnimationStateExample extends ExampleBase { runWalkButton.addActionListener(new ActionListener() { boolean walk = true; + @Override public void actionPerformed(final ActionEvent event) { if (!walk) { if (manager.getBaseAnimationLayer().doTransition("walk")) { @@ -181,6 +182,7 @@ public class AnimationStateExample extends ExampleBase { punchButton .setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, runWalkButton, Alignment.BOTTOM_LEFT, 0, -5)); punchButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { manager.findAnimationLayer("punch").setCurrentState("punch_right", true); punchButton.setEnabled(false); @@ -192,6 +194,7 @@ public class AnimationStateExample extends ExampleBase { playPauseButton.setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, punchButton, Alignment.BOTTOM_LEFT, 0, -5)); playPauseButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { if (playPauseButton.getText().equals("Pause")) { manager.pause(); @@ -208,6 +211,7 @@ public class AnimationStateExample extends ExampleBase { stopButton .setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, playPauseButton, Alignment.BOTTOM_LEFT, 0, -5)); stopButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { manager.stop(); playPauseButton.setButtonText("Play"); @@ -220,6 +224,7 @@ public class AnimationStateExample extends ExampleBase { .setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, stopButton, Alignment.BOTTOM_LEFT, 0, -5)); resetAnimCheck.setSelected(false); resetAnimCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { manager.setResetClipsOnStop(resetAnimCheck.isSelected()); @@ -232,6 +237,7 @@ public class AnimationStateExample extends ExampleBase { 0, -5)); gpuSkinningCheck.setSelected(false); gpuSkinningCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { _root.acceptVisitor(new Visitor() { @Override @@ -257,6 +263,7 @@ public class AnimationStateExample extends ExampleBase { vboCheck.setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, gpuSkinningCheck, Alignment.BOTTOM_LEFT, 0, -5)); vboCheck.setSelected(false); vboCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { skNode.getSceneHints().setDataMode(vboCheck.isSelected() ? DataMode.VBO : DataMode.Arrays); gpuShader.setUseAttributeVBO(vboCheck.isSelected()); @@ -270,6 +277,7 @@ public class AnimationStateExample extends ExampleBase { skeletonCheck.setSelected(showSkeleton); skeletonCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { showSkeleton = skeletonCheck.isSelected(); boneLabelCheck.setEnabled(showSkeleton); @@ -283,6 +291,7 @@ public class AnimationStateExample extends ExampleBase { boneLabelCheck.setEnabled(showSkeleton); boneLabelCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { showJointLabels = boneLabelCheck.isSelected(); } @@ -396,6 +405,7 @@ public class AnimationStateExample extends ExampleBase { // Add a call back to load clips. final InputStore input = new InputStore(); input.getClips().setMissCallback(new MissingCallback<String, AnimationClip>() { + @Override public AnimationClip getValue(final String key) { try { final ColladaStorage storage1 = colladaImporter.load("collada/skeleton/" + key + ".dae"); @@ -421,6 +431,7 @@ public class AnimationStateExample extends ExampleBase { // add callback for our UI manager.findClipInstance("skeleton.punch").addAnimationListener(new AnimationListener() { + @Override public void animationFinished(final AnimationClipInstance source) { punchButton.setEnabled(true); } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ColladaExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ColladaExample.java index f9c93d2..f769883 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ColladaExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ColladaExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -151,6 +151,7 @@ public class ColladaExample extends ExampleBase { final UIButton loadSceneButton = new UIButton("Load next scene"); loadSceneButton.setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, basePanel, Alignment.TOP_LEFT, 5, -5)); loadSceneButton.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { final File file = daeFiles.get(fileIndex); try { @@ -169,6 +170,7 @@ public class ColladaExample extends ExampleBase { .setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, loadSceneButton, Alignment.BOTTOM_LEFT, 0, -5)); skinCheck.setSelected(true); skinCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { colladaNode.getSceneHints().setCullHint(skinCheck.isSelected() ? CullHint.Dynamic : CullHint.Always); } @@ -180,6 +182,7 @@ public class ColladaExample extends ExampleBase { skeletonCheck.setLayoutData(new AnchorLayoutData(Alignment.TOP_LEFT, skinCheck, Alignment.BOTTOM_LEFT, 0, -5)); skeletonCheck.setSelected(showSkeleton); skeletonCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { showSkeleton = skeletonCheck.isSelected(); boneLabelCheck.setEnabled(showSkeleton); @@ -192,6 +195,7 @@ public class ColladaExample extends ExampleBase { boneLabelCheck.setSelected(false); boneLabelCheck.setEnabled(showSkeleton); boneLabelCheck.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { showJointLabels = boneLabelCheck.isSelected(); } @@ -355,7 +359,7 @@ public class ColladaExample extends ExampleBase { private List<File> findFiles(final File rootDir, final String name, List<File> fileList) { if (fileList == null) { - fileList = new ArrayList<File>(); + fileList = new ArrayList<>(); } final File[] files = rootDir.listFiles(); for (int i = 0; i < files.length; i++) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ColladaManualAnimationExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ColladaManualAnimationExample.java index f5008ac..73a93cf 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ColladaManualAnimationExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ColladaManualAnimationExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -232,6 +232,7 @@ public class ColladaManualAnimationExample extends ExampleBase { _root.getSceneHints().setCullHint(CullHint.Never); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.K), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showSkeleton = !showSkeleton; if (showSkeleton) { @@ -243,6 +244,7 @@ public class ColladaManualAnimationExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.M), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showMesh = !showMesh; colladaNode.getSceneHints().setCullHint(showMesh ? CullHint.Dynamic : CullHint.Always); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ExportImportExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ExportImportExample.java index 75fc092..c638e69 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ExportImportExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ExportImportExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/FireballTrigger.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/FireballTrigger.java index 42d1411..c783518 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/FireballTrigger.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/FireballTrigger.java @@ -33,6 +33,7 @@ public class FireballTrigger implements TriggerCallback { example = AnimationDemoExample.instance; } + @Override public void doTrigger(final SkeletonPose applyToPose, final AnimationManager manager) { GameTaskQueueManager.getManager(example.getCanvas().getCanvasRenderer().getRenderContext()).update( new Callable<Void>() { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/PrimitiveSkeletonExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/PrimitiveSkeletonExample.java index d17d162..1274866 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/PrimitiveSkeletonExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/PrimitiveSkeletonExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -181,6 +181,7 @@ public class PrimitiveSkeletonExample extends ExampleBase { _root.getSceneHints().setCullHint(CullHint.Never); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.K), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showSkeleton = !showSkeleton; if (showSkeleton) { @@ -192,6 +193,7 @@ public class PrimitiveSkeletonExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { useGPU = !useGPU; arm1.getGPUShader().setEnabled(useGPU); @@ -207,6 +209,7 @@ public class PrimitiveSkeletonExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { runAnimation = !runAnimation; if (runAnimation) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ScenegraphTree.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ScenegraphTree.java index 38612f2..66cda26 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ScenegraphTree.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/ScenegraphTree.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -59,6 +59,7 @@ public class ScenegraphTree { this.textArea = textArea; } + @Override public void valueChanged(final TreeSelectionEvent e) { if (e.getNewLeadSelectionPath() == null || e.getNewLeadSelectionPath().getLastPathComponent() == null) { return; @@ -103,6 +104,7 @@ public class ScenegraphTree { rootNode = node; } + @Override public Object getChild(final Object parent, final int index) { if (parent instanceof Node) { final Node parentNode = (Node) parent; @@ -111,6 +113,7 @@ public class ScenegraphTree { return null; } + @Override public int getChildCount(final Object parent) { if (parent instanceof Node) { final Node parentNode = (Node) parent; @@ -119,6 +122,7 @@ public class ScenegraphTree { return 0; } + @Override public int getIndexOfChild(final Object parent, final Object child) { if (parent instanceof Node && child instanceof Spatial) { final Node parentNode = (Node) parent; @@ -127,18 +131,23 @@ public class ScenegraphTree { return 0; } + @Override public Object getRoot() { return rootNode; } + @Override public boolean isLeaf(final Object node) { return !(node instanceof Node); } + @Override public void addTreeModelListener(final TreeModelListener l) {} + @Override public void removeTreeModelListener(final TreeModelListener l) {} + @Override public void valueForPathChanged(final TreePath path, final Object newValue) {} } } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleColladaExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleColladaExample.java index 49facdd..ed63598 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleColladaExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleColladaExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleMd2Example.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleMd2Example.java index 2a92205..a4bf458 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleMd2Example.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleMd2Example.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleMd3Example.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleMd3Example.java new file mode 100644 index 0000000..b82f23f --- /dev/null +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleMd3Example.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2008-2014 Ardor Labs, Inc. + * + * This file is part of Ardor3D. + * + * Ardor3D is free software: you can redistribute it and/or modify it + * under the terms of its license which may be found in the accompanying + * LICENSE file or at <http://www.ardor3d.com/LICENSE>. + */ + +package com.ardor3d.example.pipeline; + +import com.ardor3d.example.ExampleBase; +import com.ardor3d.example.Purpose; +import com.ardor3d.extension.model.md3.Md3DataStore; +import com.ardor3d.extension.model.md3.Md3Importer; +import com.ardor3d.math.MathUtils; +import com.ardor3d.math.Quaternion; +import com.ardor3d.math.Vector3; +import com.ardor3d.scenegraph.Node; + +/** + * Simplest example of loading a model in MD3 format. FIXME update the thumbnail + */ +@Purpose(htmlDescriptionKey = "com.ardor3d.example.pipeline.SimpleMd3Example", // +thumbnailPath = "com/ardor3d/example/media/thumbnails/pipeline_SimpleMd2Example.jpg", // +maxHeapMemory = 64) +public class SimpleMd3Example extends ExampleBase { + public static void main(final String[] args) { + ExampleBase.start(SimpleMd3Example.class); + } + + @Override + protected void initExample() { + _canvas.setTitle("Ardor3D - Simple Md3 Example"); + _canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 5, 20)); + + // Load the scene + final long time = System.currentTimeMillis(); + final Md3Importer importer = new Md3Importer(); + // try { + // importer.setTextureLocator(new MultiFormatResourceLocator(ResourceLocatorTool.getClassPathResource( + // SimpleObjExample.class, "com/ardor3d/example/media/models/md2/"), ".dds", ".jpg", ".png", ".tga", + // ".pcx")); + // } catch (final URISyntaxException ex) { + // ex.printStackTrace(); + // } + + final Md3DataStore storage = importer.load("md3/barrel1.md3"); + System.out.println("Importing Took " + (System.currentTimeMillis() - time) + " ms"); + + final Node model = storage.getScene(); + // md2 models are usually z-up - switch to y-up + model.setRotation(new Quaternion().fromAngleAxis(-MathUtils.HALF_PI, Vector3.UNIT_X)); + // attack to root + _root.attachChild(model); + + // speed us up a little + // final KeyframeController<Mesh> controller = storage.getController(); + // controller.setSpeed(8); + // controller.setRepeatType(RepeatType.WRAP); + } +} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleObjExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleObjExample.java index 19bbe1b..09ebac6 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleObjExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleObjExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimplePlyExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimplePlyExample.java new file mode 100644 index 0000000..e038f69 --- /dev/null +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimplePlyExample.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2008-2014 Ardor Labs, Inc. + * + * This file is part of Ardor3D. + * + * Ardor3D is free software: you can redistribute it and/or modify it + * under the terms of its license which may be found in the accompanying + * LICENSE file or at <http://www.ardor3d.com/LICENSE>. + */ + +package com.ardor3d.example.pipeline; + +import java.net.URISyntaxException; + +import com.ardor3d.example.ExampleBase; +import com.ardor3d.example.Purpose; +import com.ardor3d.extension.model.ply.PlyGeometryStore; +import com.ardor3d.extension.model.ply.PlyImporter; +import com.ardor3d.math.MathUtils; +import com.ardor3d.math.Quaternion; +import com.ardor3d.math.Vector3; +import com.ardor3d.scenegraph.Node; +import com.ardor3d.util.resource.ResourceLocatorTool; +import com.ardor3d.util.resource.SimpleResourceLocator; + +/** + * Simplest example of loading a PLY model. + */ +@Purpose(htmlDescriptionKey = "com.ardor3d.example.pipeline.SimplePlyExample", // + thumbnailPath = "com/ardor3d/example/media/thumbnails/pipeline_SimplePlyExample.jpg", // + maxHeapMemory = 64) +public class SimplePlyExample extends ExampleBase { + public static void main(final String[] args) { + ExampleBase.start(SimplePlyExample.class); + } + + @Override + protected void initExample() { + _canvas.setTitle("Ardor3D - Simple Ply Example"); + _canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(3.5, 1.5, 5)); + + // Load the PLY scene + final long time = System.currentTimeMillis(); + final PlyImporter importer = new PlyImporter(); + try { + importer.setTextureLocator(new SimpleResourceLocator(ResourceLocatorTool + .getClassPathResource(SimpleObjExample.class, "com/ardor3d/example/media/models/ply/"))); + } catch (final URISyntaxException ex) { + ex.printStackTrace(); + } + final PlyGeometryStore storage = importer.load("ply/big_spider.ply"); + System.out.println("Importing Took " + (System.currentTimeMillis() - time) + " ms"); + + final Node model = storage.getScene(); + // the ply model is usually z-up - switch to y-up + model.setRotation(new Quaternion().fromAngleAxis(-MathUtils.HALF_PI, Vector3.UNIT_X)); + _root.attachChild(model); + } +} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleStlExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleStlExample.java new file mode 100644 index 0000000..0631511 --- /dev/null +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleStlExample.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2008-2014 Ardor Labs, Inc. + * + * This file is part of Ardor3D. + * + * Ardor3D is free software: you can redistribute it and/or modify it + * under the terms of its license which may be found in the accompanying + * LICENSE file or at <http://www.ardor3d.com/LICENSE>. + */ + +package com.ardor3d.example.pipeline; + +import com.ardor3d.example.ExampleBase; +import com.ardor3d.example.Purpose; +import com.ardor3d.extension.model.stl.StlGeometryStore; +import com.ardor3d.extension.model.stl.StlImporter; +import com.ardor3d.math.Vector3; + +/** + * Simplest example of loading a STL model. + */ +@Purpose(htmlDescriptionKey = "com.ardor3d.example.pipeline.SimpleStlExample", // + thumbnailPath = "com/ardor3d/example/media/thumbnails/pipeline_SimpleStlExample.jpg", // + maxHeapMemory = 64) +public class SimpleStlExample extends ExampleBase { + public static void main(final String[] args) { + ExampleBase.start(SimpleStlExample.class); + } + + @Override + protected void initExample() { + _canvas.setTitle("Ardor3D - Simple Stl Example"); + _canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 0, 70)); + + // Load the STL scene + final long time = System.currentTimeMillis(); + final StlImporter importer = new StlImporter(); + final StlGeometryStore storage = importer.load("stl/space_invader_magnet.stl"); + System.out.println("Importing Took " + (System.currentTimeMillis() - time) + " ms"); + + _root.attachChild(storage.getScene()); + } +}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/BillboardNodeExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/BillboardNodeExample.java index cba3651..8e4cdc5 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/BillboardNodeExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/BillboardNodeExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -111,6 +111,7 @@ public class BillboardNodeExample extends ExampleBase { } _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { int ordinal = billboards[0].getAlignment().ordinal() + 1; if (ordinal > BillboardAlignment.values().length - 1) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/BillboardNodeZExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/BillboardNodeZExample.java index 01063be..ef21b6b 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/BillboardNodeZExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/BillboardNodeZExample.java @@ -118,6 +118,7 @@ public class BillboardNodeZExample extends ExampleBase { } _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { int ordinal = billboards[0].getAlignment().ordinal() + 1; if (ordinal > BillboardAlignment.values().length - 1) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ClipStateExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ClipStateExample.java index 511c0d4..d08f9c4 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ClipStateExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ClipStateExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/CombinerExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/CombinerExample.java index 0fd57d4..63828ff 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/CombinerExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/CombinerExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DegenerateTrianglesExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DegenerateTrianglesExample.java index c9a859d..9884bd5 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DegenerateTrianglesExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DegenerateTrianglesExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -105,6 +105,7 @@ public class DegenerateTrianglesExample extends ExampleBase { degenerateStripMesh.getSceneHints().setCullHint(CullHint.Always); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showDegenerateMesh = !showDegenerateMesh; if (showDegenerateMesh) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DisplayListDelegateExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DisplayListDelegateExample.java index 2370a0f..a44fe78 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DisplayListDelegateExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DisplayListDelegateExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -153,6 +153,7 @@ public class DisplayListDelegateExample extends ExampleBase { updateText(); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showingCompiled = !showingCompiled; if (showingCompiled) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DisplayListExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DisplayListExample.java index 14ee582..61a3984 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DisplayListExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/DisplayListExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -164,6 +164,7 @@ public class DisplayListExample extends ExampleBase { _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { private boolean useDL = true; + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { useDL = !useDL; if (useDL) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GLSLRibbonExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GLSLRibbonExample.java index 7090dbc..62d3e7e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GLSLRibbonExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GLSLRibbonExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GeneratedTexturesExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GeneratedTexturesExample.java index 4fdc002..0cb1dce 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GeneratedTexturesExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GeneratedTexturesExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -254,6 +254,7 @@ public class GeneratedTexturesExample extends ExampleBase { float ratio = zoom ? 0 : 1; float zSpeed = 1; + @Override public void update(final double time, final UIPanel caller) { // update ratio ratio += (zoom ? 1 : -1) * zSpeed * time; @@ -287,6 +288,7 @@ public class GeneratedTexturesExample extends ExampleBase { super.registerInputTriggers(); _logicalLayer.registerTrigger(new InputTrigger(TriggerConditions.mouseMoved(), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { if (!allowClicks || !zoom) { return; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GeometryInstancingExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GeometryInstancingExample.java index 52bac15..79557c5 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GeometryInstancingExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/GeometryInstancingExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2010 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -138,6 +138,7 @@ public class GeometryInstancingExample extends ExampleBase { generateSpheres(unInstancedBase, false, nrOfObjects); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { vboMode = (vboMode + 1) % 3; if (vboMode == 0) { @@ -146,6 +147,7 @@ public class GeometryInstancingExample extends ExampleBase { // run this in the opengl thread GameTaskQueueManager.getManager(_canvas.getCanvasRenderer().getRenderContext()).render( new Callable<Void>() { + @Override public Void call() throws Exception { final DeleteVBOsVisitor viz = new DeleteVBOsVisitor(_canvas.getCanvasRenderer() .getRenderer()); @@ -165,6 +167,7 @@ public class GeometryInstancingExample extends ExampleBase { _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.I), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { instancingEnabled = !instancingEnabled; if (instancingEnabled) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MandelbrotExplorerExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MandelbrotExplorerExample.java index d9d82c5..a65989e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MandelbrotExplorerExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MandelbrotExplorerExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -97,6 +97,7 @@ public class MandelbrotExplorerExample extends ExampleBase { super.registerInputTriggers(); _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonReleasedCondition(MouseButton.LEFT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { // zoom in final MouseState mouse = inputState.getCurrent().getMouseState(); @@ -112,6 +113,7 @@ public class MandelbrotExplorerExample extends ExampleBase { })); _logicalLayer.registerTrigger(new InputTrigger(new MouseButtonReleasedCondition(MouseButton.RIGHT), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputState, final double tpf) { // zoom out final MouseState mouse = inputState.getCurrent().getMouseState(); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ManyLightsExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ManyLightsExample.java index b8d2a1c..c2b9f12 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ManyLightsExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ManyLightsExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -81,6 +81,7 @@ public class ManyLightsExample extends ExampleBase { double timeZ = rand.nextDouble() * Math.PI * 8; double speed = MathUtils.nextRandomDouble(); + @Override public void update(final double tpf, final Spatial caller) { timeX += tpf * speed; timeY += tpf * speed; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MaterialFaceExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MaterialFaceExample.java index eb84ced..716a405 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MaterialFaceExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MaterialFaceExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MeshDataSharingExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MeshDataSharingExample.java index 036632f..fc76a69 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MeshDataSharingExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MeshDataSharingExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MultiPassTextureExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MultiPassTextureExample.java index a5740ae..1407cb2 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MultiPassTextureExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MultiPassTextureExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MultiStripExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MultiStripExample.java index c5e1483..273c64f 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MultiStripExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/MultiStripExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/PointCubeExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/PointCubeExample.java index c73fa30..cb19159 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/PointCubeExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/PointCubeExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -226,21 +226,25 @@ public class PointCubeExample extends ExampleBase { super.registerInputTriggers(); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() { + @Override public void perform(final Canvas canvas, final TwoInputStates inputState, final double tpf) { _rotationEnabled = !_rotationEnabled; } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() { + @Override public void perform(final Canvas canvas, final TwoInputStates inputState, final double tpf) { _waveEnabled = !_waveEnabled; } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() { + @Override public void perform(final Canvas canvas, final TwoInputStates inputState, final double tpf) { _blurEnabled = !_blurEnabled; } })); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() { + @Override public void perform(final Canvas canvas, final TwoInputStates inputState, final double tpf) { _scaleEnabled = !_scaleEnabled; } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/PointsExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/PointsExample.java index 5b11bef..6c01d2e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/PointsExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/PointsExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderEffectsExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderEffectsExample.java index b38dd01..b979a7a 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderEffectsExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderEffectsExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -73,6 +73,7 @@ public class RenderEffectsExample extends ExampleBase { private final Matrix3 _rotate = new Matrix3(); private double _angle = 0; + @Override public void update(final double time, final Spatial caller) { // update our rotation _angle = _angle + (_timer.getTimePerFrame() * 25); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderQueueExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderQueueExample.java index 08483f8..5a9827c 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderQueueExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderQueueExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.renderer;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture.MinificationFilter;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Vector2;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.BlendState;
import com.ardor3d.renderer.state.BlendState.DestinationFunction;
import com.ardor3d.renderer.state.BlendState.SourceFunction;
import com.ardor3d.renderer.state.LightState;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.MaterialFace;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.renderer.state.ZBufferState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.hint.TransparencyType;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Torus;
import com.ardor3d.util.TextureManager;
/**
* Illustrates the Render Queue, which controls how Nodes are drawn when overlapping occurs.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.renderer.RenderQueueExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/renderer_RenderQueueExample.jpg", //
maxHeapMemory = 64)
public class RenderQueueExample extends ExampleBase {
private boolean useQueue = false;
private boolean twoPass = false;
protected Node opaques, transps, orthos;
private boolean _updateTitle;
public static void main(final String[] args) {
start(RenderQueueExample.class);
}
@Override
protected void renderExample(final Renderer renderer) {
transps.getSceneHints().setTransparencyType(twoPass ? TransparencyType.TwoPass : TransparencyType.OnePass);
if (_updateTitle) {
_canvas.setTitle("Test Render Queue - " + useQueue + " - hit 'M' to toggle Queue mode - 'R' Two Pass: - "
+ twoPass);
_updateTitle = false;
}
if (!useQueue) {
renderer.setOrtho();
renderer.draw(orthos);
renderer.unsetOrtho();
} else {
renderer.draw(orthos);
}
transps.draw(renderer);
opaques.draw(renderer);
}
@Override
protected void initExample() {
_canvas.setTitle("Test Render Queue - false - hit 'M' to toggle Queue mode - 'R' Two Pass: - false");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(10, 0, 50));
final Vector3 max = new Vector3(5, 5, 5);
final Vector3 min = new Vector3(-5, -5, -5);
opaques = new Node("Opaques");
transps = new Node("Transps");
orthos = new Node("Orthos");
transps.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
opaques.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
orthos.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
_root.attachChild(orthos);
_root.attachChild(transps);
_root.attachChild(opaques);
final Box b1 = new Box("Box", min, max);
b1.setModelBound(new BoundingBox());
b1.setTranslation(new Vector3(0, 0, -15));
opaques.attachChild(b1);
final Box b2 = new Box("Box", min, max);
b2.setModelBound(new BoundingBox());
b2.setTranslation(new Vector3(0, 0, -30));
opaques.attachChild(b2);
final Box b3 = new Box("Box", min, max);
b3.setModelBound(new BoundingBox());
b3.setTranslation(new Vector3(0, -15, -15));
opaques.attachChild(b3);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", MinificationFilter.Trilinear, true));
opaques.setRenderState(ts);
final LightState ls = new LightState();
ls.setEnabled(true);
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setDiffuse(new ColorRGBA(1, 1, 1, 1));
dLight.setDirection(new Vector3(1, 1, 1));
ls.attach(dLight);
final DirectionalLight dLight2 = new DirectionalLight();
dLight2.setEnabled(true);
dLight2.setDiffuse(new ColorRGBA(1, 1, 1, 1));
dLight2.setDirection(new Vector3(-1, -1, -1));
ls.attach(dLight2);
ls.setTwoSidedLighting(false);
transps.setRenderState(ls);
transps.getSceneHints().setLightCombineMode(LightCombineMode.Replace);
final Box tb1 = new Box("TBox Blue", min, max);
tb1.setModelBound(new BoundingBox());
tb1.setTranslation(new Vector3(0, 15, 15));
transps.attachChild(tb1);
final MaterialState ms1 = new MaterialState();
ms1.setEnabled(true);
ms1.setDiffuse(MaterialFace.FrontAndBack, new ColorRGBA(0, 0, 1, .75f));
ms1.setShininess(MaterialFace.FrontAndBack, 128);
tb1.setRenderState(ms1);
final Torus tb2 = new Torus("TBox Green", 20, 20, 3, 6);
tb2.setModelBound(new BoundingBox());
tb2.setTranslation(new Vector3(0, 0, 30));
transps.attachChild(tb2);
final MaterialState ms2 = new MaterialState();
ms2.setEnabled(true);
ms2.setDiffuse(MaterialFace.FrontAndBack, new ColorRGBA(0, 1, 0, .5f));
ms2.setShininess(MaterialFace.FrontAndBack, 128);
tb2.setRenderState(ms2);
final Box tb3 = new Box("TBox Red", min, max);
tb3.setModelBound(new BoundingBox());
tb3.setTranslation(new Vector3(0, 0, 15));
transps.attachChild(tb3);
final MaterialState ms3 = new MaterialState();
ms3.setEnabled(true);
ms3.setDiffuse(MaterialFace.FrontAndBack, new ColorRGBA(1, 0, 0, .5f));
ms3.setShininess(MaterialFace.FrontAndBack, 128);
tb3.setRenderState(ms3);
final BlendState as = new BlendState();
as.setEnabled(true);
as.setBlendEnabled(true);
as.setSourceFunction(SourceFunction.SourceAlpha);
as.setDestinationFunction(DestinationFunction.OneMinusSourceAlpha);
transps.setRenderState(as);
final Vector2 center = new Vector2(_canvas.getCanvasRenderer().getCamera().getWidth() >> 1, _canvas
.getCanvasRenderer().getCamera().getWidth() >> 1);
final Quad q1 = new Quad("Ortho Q1", 40, 40);
q1.setTranslation(new Vector3(100 + center.getX(), 100 + center.getY(), 0));
q1.getSceneHints().setOrthoOrder(1);
q1.setDefaultColor(ColorRGBA.WHITE);
q1.getSceneHints().setLightCombineMode(LightCombineMode.Off);
orthos.attachChild(q1);
final Quad q2 = new Quad("Ortho Q2", 100, 100);
q2.setTranslation(new Vector3(60 + center.getX(), 60 + center.getY(), 0));
q2.getSceneHints().setOrthoOrder(5);
q2.setDefaultColor(ColorRGBA.RED);
q2.getSceneHints().setLightCombineMode(LightCombineMode.Off);
orthos.attachChild(q2);
final Quad q3 = new Quad("Ortho Q3", 120, 60);
q3.setTranslation(new Vector3(-20 + center.getX(), -150 + center.getY(), 0));
q3.getSceneHints().setOrthoOrder(2);
q3.setDefaultColor(ColorRGBA.BLUE);
q3.getSceneHints().setLightCombineMode(LightCombineMode.Off);
orthos.attachChild(q3);
final ZBufferState zstate = new ZBufferState();
zstate.setWritable(false);
zstate.setEnabled(false);
orthos.setRenderState(zstate);
orthos.setRenderState(new LightState());
_root.getSceneHints().setCullHint(CullHint.Always);
opaques.getSceneHints().setCullHint(CullHint.Dynamic);
transps.getSceneHints().setCullHint(CullHint.Dynamic);
orthos.getSceneHints().setCullHint(CullHint.Never);
}
@Override
protected void registerInputTriggers() {
super.registerInputTriggers();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.M), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (useQueue) {
transps.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
opaques.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
orthos.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
} else {
transps.getSceneHints().setRenderBucketType(RenderBucketType.Transparent);
opaques.getSceneHints().setRenderBucketType(RenderBucketType.Opaque);
orthos.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
}
useQueue = !useQueue;
_updateTitle = true;
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
twoPass = !twoPass;
_updateTitle = true;
}
}));
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.renderer;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture.MinificationFilter;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Vector2;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.BlendState;
import com.ardor3d.renderer.state.BlendState.DestinationFunction;
import com.ardor3d.renderer.state.BlendState.SourceFunction;
import com.ardor3d.renderer.state.LightState;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.MaterialFace;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.renderer.state.ZBufferState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.hint.TransparencyType;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Torus;
import com.ardor3d.util.TextureManager;
/**
* Illustrates the Render Queue, which controls how Nodes are drawn when overlapping occurs.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.renderer.RenderQueueExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/renderer_RenderQueueExample.jpg", //
maxHeapMemory = 64)
public class RenderQueueExample extends ExampleBase {
private boolean useQueue = false;
private boolean twoPass = false;
protected Node opaques, transps, orthos;
private boolean _updateTitle;
public static void main(final String[] args) {
start(RenderQueueExample.class);
}
@Override
protected void renderExample(final Renderer renderer) {
transps.getSceneHints().setTransparencyType(twoPass ? TransparencyType.TwoPass : TransparencyType.OnePass);
if (_updateTitle) {
_canvas.setTitle("Test Render Queue - " + useQueue + " - hit 'M' to toggle Queue mode - 'R' Two Pass: - "
+ twoPass);
_updateTitle = false;
}
if (!useQueue) {
renderer.setOrtho();
renderer.draw(orthos);
renderer.unsetOrtho();
} else {
renderer.draw(orthos);
}
transps.draw(renderer);
opaques.draw(renderer);
}
@Override
protected void initExample() {
_canvas.setTitle("Test Render Queue - false - hit 'M' to toggle Queue mode - 'R' Two Pass: - false");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(10, 0, 50));
final Vector3 max = new Vector3(5, 5, 5);
final Vector3 min = new Vector3(-5, -5, -5);
opaques = new Node("Opaques");
transps = new Node("Transps");
orthos = new Node("Orthos");
transps.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
opaques.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
orthos.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
_root.attachChild(orthos);
_root.attachChild(transps);
_root.attachChild(opaques);
final Box b1 = new Box("Box", min, max);
b1.setModelBound(new BoundingBox());
b1.setTranslation(new Vector3(0, 0, -15));
opaques.attachChild(b1);
final Box b2 = new Box("Box", min, max);
b2.setModelBound(new BoundingBox());
b2.setTranslation(new Vector3(0, 0, -30));
opaques.attachChild(b2);
final Box b3 = new Box("Box", min, max);
b3.setModelBound(new BoundingBox());
b3.setTranslation(new Vector3(0, -15, -15));
opaques.attachChild(b3);
final TextureState ts = new TextureState();
ts.setEnabled(true);
ts.setTexture(TextureManager.load("images/ardor3d_white_256.jpg", MinificationFilter.Trilinear, true));
opaques.setRenderState(ts);
final LightState ls = new LightState();
ls.setEnabled(true);
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setDiffuse(new ColorRGBA(1, 1, 1, 1));
dLight.setDirection(new Vector3(1, 1, 1));
ls.attach(dLight);
final DirectionalLight dLight2 = new DirectionalLight();
dLight2.setEnabled(true);
dLight2.setDiffuse(new ColorRGBA(1, 1, 1, 1));
dLight2.setDirection(new Vector3(-1, -1, -1));
ls.attach(dLight2);
ls.setTwoSidedLighting(false);
transps.setRenderState(ls);
transps.getSceneHints().setLightCombineMode(LightCombineMode.Replace);
final Box tb1 = new Box("TBox Blue", min, max);
tb1.setModelBound(new BoundingBox());
tb1.setTranslation(new Vector3(0, 15, 15));
transps.attachChild(tb1);
final MaterialState ms1 = new MaterialState();
ms1.setEnabled(true);
ms1.setDiffuse(MaterialFace.FrontAndBack, new ColorRGBA(0, 0, 1, .75f));
ms1.setShininess(MaterialFace.FrontAndBack, 128);
tb1.setRenderState(ms1);
final Torus tb2 = new Torus("TBox Green", 20, 20, 3, 6);
tb2.setModelBound(new BoundingBox());
tb2.setTranslation(new Vector3(0, 0, 30));
transps.attachChild(tb2);
final MaterialState ms2 = new MaterialState();
ms2.setEnabled(true);
ms2.setDiffuse(MaterialFace.FrontAndBack, new ColorRGBA(0, 1, 0, .5f));
ms2.setShininess(MaterialFace.FrontAndBack, 128);
tb2.setRenderState(ms2);
final Box tb3 = new Box("TBox Red", min, max);
tb3.setModelBound(new BoundingBox());
tb3.setTranslation(new Vector3(0, 0, 15));
transps.attachChild(tb3);
final MaterialState ms3 = new MaterialState();
ms3.setEnabled(true);
ms3.setDiffuse(MaterialFace.FrontAndBack, new ColorRGBA(1, 0, 0, .5f));
ms3.setShininess(MaterialFace.FrontAndBack, 128);
tb3.setRenderState(ms3);
final BlendState as = new BlendState();
as.setEnabled(true);
as.setBlendEnabled(true);
as.setSourceFunction(SourceFunction.SourceAlpha);
as.setDestinationFunction(DestinationFunction.OneMinusSourceAlpha);
transps.setRenderState(as);
final Vector2 center = new Vector2(_canvas.getCanvasRenderer().getCamera().getWidth() >> 1, _canvas
.getCanvasRenderer().getCamera().getWidth() >> 1);
final Quad q1 = new Quad("Ortho Q1", 40, 40);
q1.setTranslation(new Vector3(100 + center.getX(), 100 + center.getY(), 0));
q1.getSceneHints().setOrthoOrder(1);
q1.setDefaultColor(ColorRGBA.WHITE);
q1.getSceneHints().setLightCombineMode(LightCombineMode.Off);
orthos.attachChild(q1);
final Quad q2 = new Quad("Ortho Q2", 100, 100);
q2.setTranslation(new Vector3(60 + center.getX(), 60 + center.getY(), 0));
q2.getSceneHints().setOrthoOrder(5);
q2.setDefaultColor(ColorRGBA.RED);
q2.getSceneHints().setLightCombineMode(LightCombineMode.Off);
orthos.attachChild(q2);
final Quad q3 = new Quad("Ortho Q3", 120, 60);
q3.setTranslation(new Vector3(-20 + center.getX(), -150 + center.getY(), 0));
q3.getSceneHints().setOrthoOrder(2);
q3.setDefaultColor(ColorRGBA.BLUE);
q3.getSceneHints().setLightCombineMode(LightCombineMode.Off);
orthos.attachChild(q3);
final ZBufferState zstate = new ZBufferState();
zstate.setWritable(false);
zstate.setEnabled(false);
orthos.setRenderState(zstate);
orthos.setRenderState(new LightState());
_root.getSceneHints().setCullHint(CullHint.Always);
opaques.getSceneHints().setCullHint(CullHint.Dynamic);
transps.getSceneHints().setCullHint(CullHint.Dynamic);
orthos.getSceneHints().setCullHint(CullHint.Never);
}
@Override
protected void registerInputTriggers() {
super.registerInputTriggers();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.M), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (useQueue) {
transps.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
opaques.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
orthos.getSceneHints().setRenderBucketType(RenderBucketType.Skip);
} else {
transps.getSceneHints().setRenderBucketType(RenderBucketType.Transparent);
opaques.getSceneHints().setRenderBucketType(RenderBucketType.Opaque);
orthos.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
}
useQueue = !useQueue;
_updateTitle = true;
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
twoPass = !twoPass;
_updateTitle = true;
}
}));
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderTextureCubeMapExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderTextureCubeMapExample.java index d515ed9..680aa38 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderTextureCubeMapExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderTextureCubeMapExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -106,6 +106,7 @@ public class RenderTextureCubeMapExample extends ExampleBase { final Pyramid b = new Pyramid("box", 2, 3); b.setRotation(new Quaternion().fromAngleNormalAxis(MathUtils.PI, Vector3.UNIT_X)); b.addController(new SpatialController<Spatial>() { + @Override public void update(final double time, final Spatial caller) { b.setTranslation(-3, 6 * MathUtils.sin(_timer.getTimeInSeconds()), 0); }; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderTextureSideBySideExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderTextureSideBySideExample.java index 32bbe37..8e62ff1 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderTextureSideBySideExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/RenderTextureSideBySideExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/SphereComparisonsExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/SphereComparisonsExample.java index dd6bd63..120286b 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/SphereComparisonsExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/SphereComparisonsExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/StereoExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/StereoExample.java index 7c5905d..08b53f2 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/StereoExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/StereoExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -115,6 +115,7 @@ public class StereoExample extends ExampleBase { _root.setTranslation(0, -1, 0); } + @SuppressWarnings("unused") @Override protected void renderExample(final Renderer renderer) { @@ -168,6 +169,6 @@ public class StereoExample extends ExampleBase { @Override protected void renderDebug(final Renderer renderer) { - // ignore. We'll call super on the individual left/right renderings. + // ignore. We'll call super on the individual left/right renderings. } } diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/TexCombineExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/TexCombineExample.java index 675b32d..8be916e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/TexCombineExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/TexCombineExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/Texture3DExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/Texture3DExample.java index 9884266..e0745f7 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/Texture3DExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/Texture3DExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -11,6 +11,7 @@ package com.ardor3d.example.renderer; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.List; import com.ardor3d.example.ExampleBase; @@ -31,7 +32,6 @@ import com.ardor3d.math.ColorRGBA; import com.ardor3d.renderer.state.TextureState; import com.ardor3d.scenegraph.shape.Sphere; import com.ardor3d.util.TextureKey; -import com.google.common.collect.Lists; /** * Very simple example showing use of a Texture3D texture. @@ -59,6 +59,7 @@ public class Texture3DExample extends ExampleBase { _root.attachChild(sp); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { final Texture tex = createTexture(); tex.setEnvironmentalMapMode(EnvironmentalMapMode.ObjectLinear); @@ -77,7 +78,7 @@ public class Texture3DExample extends ExampleBase { img.setHeight(32); img.setDepth(32); - final List<ByteBuffer> data = Lists.newArrayList(); + final List<ByteBuffer> data = new ArrayList<>(); for (int i = 0; i < 32; i++) { final Image colorImage = GeneratedImageFactory .createSolidColorImage(ColorRGBA.randomColor(null), false, 32); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/TextureProjectionExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/TextureProjectionExample.java index 8c0fd39..a990a19 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/TextureProjectionExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/TextureProjectionExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/UpdateTextureExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/UpdateTextureExample.java index c4b5ae3..33e55aa 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/UpdateTextureExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/UpdateTextureExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -147,6 +147,7 @@ public class UpdateTextureExample extends ExampleBase { _root.attachChild(keyText); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { mode++; mode %= 3; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/VBOSpeedExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/VBOSpeedExample.java index c82a548..4406db2 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/VBOSpeedExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/VBOSpeedExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -115,6 +115,7 @@ public class VBOSpeedExample extends ExampleBase { } _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { vboMode = (vboMode + 1) % 3; if (vboMode == 0) { @@ -123,6 +124,7 @@ public class VBOSpeedExample extends ExampleBase { // run this in the opengl thread GameTaskQueueManager.getManager(_canvas.getCanvasRenderer().getRenderContext()).render( new Callable<Void>() { + @Override public Void call() throws Exception { final DeleteVBOsVisitor viz = new DeleteVBOsVisitor(_canvas.getCanvasRenderer() .getRenderer()); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ViewportExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ViewportExample.java index 1d827da..6b32e4c 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ViewportExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/ViewportExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -120,6 +120,7 @@ public class ViewportExample extends ExampleBase { super.registerInputTriggers(); _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { fullViewport = !fullViewport; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/WireframeGeometryShaderExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/WireframeGeometryShaderExample.java index bbee1e9..66cb5b1 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/WireframeGeometryShaderExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/WireframeGeometryShaderExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/AtlasExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/AtlasExample.java index ce1c13e..f2eb734 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/AtlasExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/AtlasExample.java @@ -1,9 +1,9 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * - * Ardor3D is free software: you can redistribute it and/or modify it + * Ardor3D is free software: you can redistribute it and/or modify it * under the terms of its license which may be found in the accompanying * LICENSE file or at <http://www.ardor3d.com/LICENSE>. */ @@ -13,6 +13,7 @@ package com.ardor3d.example.renderer.utils.atlas; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; @@ -48,13 +49,12 @@ import com.ardor3d.ui.text.BasicText; import com.ardor3d.util.ReadOnlyTimer; import com.ardor3d.util.TextureManager; import com.ardor3d.util.geom.MeshCombiner; -import com.google.common.collect.Lists; /** * Example showing how to use the TexturePacker to create a texture atlas. Also shows the benefits of using it together * with the MeshCombiner. */ -@Purpose(htmlDescriptionKey = "com.ardor3d.example.basic.AtlasExample", // +@Purpose(htmlDescriptionKey = "com.ardor3d.example.renderer.utils.atlas.AtlasExample", // thumbnailPath = "com/ardor3d/example/media/thumbnails/basic_BoxExample.jpg", // maxHeapMemory = 64) public class AtlasExample extends ExampleBase { @@ -111,6 +111,7 @@ public class AtlasExample extends ExampleBase { // Pack textures into atlas _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { packIntoAtlas(boxNode); } @@ -118,6 +119,7 @@ public class AtlasExample extends ExampleBase { // Combine into one mesh _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { final Mesh merged = MeshCombiner.combine(boxNode); boxNode.detachAllChildren(); @@ -127,6 +129,7 @@ public class AtlasExample extends ExampleBase { // Combine into one mesh _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { resetBoxes(); } @@ -155,7 +158,7 @@ public class AtlasExample extends ExampleBase { private void packIntoAtlas(final Spatial spatial) { // Gather up all meshes to do the atlas operation on - final List<Mesh> meshes = Lists.newArrayList(); + final List<Mesh> meshes = new ArrayList<>(); final Visitor visitor = new Visitor() { @Override public void visit(final Spatial spatial) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/AtlasExampleMultiTextured.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/AtlasExampleMultiTextured.java index e8e4921..5338aef 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/AtlasExampleMultiTextured.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/AtlasExampleMultiTextured.java @@ -1,9 +1,9 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * - * Ardor3D is free software: you can redistribute it and/or modify it + * Ardor3D is free software: you can redistribute it and/or modify it * under the terms of its license which may be found in the accompanying * LICENSE file or at <http://www.ardor3d.com/LICENSE>. */ @@ -13,6 +13,7 @@ package com.ardor3d.example.renderer.utils.atlas; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; @@ -49,13 +50,12 @@ import com.ardor3d.ui.text.BasicText; import com.ardor3d.util.ReadOnlyTimer; import com.ardor3d.util.TextureManager; import com.ardor3d.util.geom.MeshCombiner; -import com.google.common.collect.Lists; /** * Example showing how to use the TexturePacker to create a texture atlas. Also shows the benefits of using it together * with the MeshCombiner. */ -@Purpose(htmlDescriptionKey = "com.ardor3d.example.basic.AtlasExampleMultiTextured", // +@Purpose(htmlDescriptionKey = "com.ardor3d.example.renderer.utils.atlas.AtlasExampleMultiTextured", // thumbnailPath = "com/ardor3d/example/media/thumbnails/basic_BoxExample.jpg", // maxHeapMemory = 64) public class AtlasExampleMultiTextured extends ExampleBase { @@ -112,6 +112,7 @@ public class AtlasExampleMultiTextured extends ExampleBase { // Pack textures into atlas _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { packIntoAtlas(boxNode); } @@ -119,6 +120,7 @@ public class AtlasExampleMultiTextured extends ExampleBase { // Combine into one mesh _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { final Mesh merged = MeshCombiner.combine(boxNode); boxNode.detachAllChildren(); @@ -128,6 +130,7 @@ public class AtlasExampleMultiTextured extends ExampleBase { // Combine into one mesh _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() { + @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { resetBoxes(); } @@ -156,7 +159,7 @@ public class AtlasExampleMultiTextured extends ExampleBase { private void packIntoAtlas(final Spatial spatial) { // Gather up all meshes to do the atlas operation on - final List<Mesh> meshes = Lists.newArrayList(); + final List<Mesh> meshes = new ArrayList<>(); final Visitor visitor = new Visitor() { @Override public void visit(final Spatial spatial) { diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/TestAtlasPacker.java b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/TestAtlasPacker.java index 06db12a..2df7c4e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/TestAtlasPacker.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/renderer/utils/atlas/TestAtlasPacker.java @@ -15,7 +15,6 @@ import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; -import com.ardor3d.extension.atlas.AtlasNode; import com.ardor3d.extension.atlas.AtlasPacker; /** @@ -30,7 +29,7 @@ public class TestAtlasPacker { final Random rand = new Random(); for (int i = 0; i < 2000; i++) { - final AtlasNode node = packer.insert(rand.nextInt(100) + 10, rand.nextInt(100) + 10); + /* final AtlasNode node = */packer.insert(rand.nextInt(100) + 10, rand.nextInt(100) + 10); } final JFrame frame = new JFrame("Pack"); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ArrayTerrainExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ArrayTerrainExample.java index bdebb18..0c7bc5b 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ArrayTerrainExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ArrayTerrainExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.heightmap.MidPointHeightMapGenerator;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a
* float array. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ArrayTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ArrayTerrainExample.jpg", //
maxHeapMemory = 128)
public class ArrayTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Mesh arrow = new Box("normal", new Vector3(-0.2, -0.2, 0), new Vector3(0.2, 0.2, 4));
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
private double counter = 0;
private int frames = 0;
public static void main(final String[] args) {
ExampleBase.start(ArrayTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = frames / counter;
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
final Vector3 intersectionNormal = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionNormal(0);
final Matrix3 rotation = new Matrix3();
rotation.lookAt(intersectionNormal, Vector3.UNIT_Z);
arrow.setRotation(rotation);
arrow.setTranslation(intersectionPoint);
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
arrow.getSceneHints().setAllPickingHints(false);
arrow.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(arrow);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
final int SIZE = 2048;
final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.6f);
raw.setHeightRange(0.2f);
final float[] heightMap = raw.getHeightData();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 300, 1));
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
arrow.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
arrow.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() + 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() - 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.heightmap.MidPointHeightMapGenerator;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a
* float array. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ArrayTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ArrayTerrainExample.jpg", //
maxHeapMemory = 128)
public class ArrayTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Mesh arrow = new Box("normal", new Vector3(-0.2, -0.2, 0), new Vector3(0.2, 0.2, 4));
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
private double counter = 0;
private int frames = 0;
public static void main(final String[] args) {
ExampleBase.start(ArrayTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = frames / counter;
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
final Vector3 intersectionNormal = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionNormal(0);
final Matrix3 rotation = new Matrix3();
rotation.lookAt(intersectionNormal, Vector3.UNIT_Z);
arrow.setRotation(rotation);
arrow.setTranslation(intersectionPoint);
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
arrow.getSceneHints().setAllPickingHints(false);
arrow.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(arrow);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
final int SIZE = 2048;
final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.6f);
raw.setHeightRange(0.2f);
final float[] heightMap = raw.getHeightData();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 300, 1));
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
arrow.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
arrow.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() + 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() - 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ImageMapTerrainExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ImageMapTerrainExample.java index 02a004e..4e323ab 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ImageMapTerrainExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ImageMapTerrainExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.awt.image.BufferedImage;
import java.util.concurrent.Callable;
import javax.imageio.ImageIO;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.heightmap.ImageHeightMap;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Image;
import com.ardor3d.image.util.awt.AWTImageLoader;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.resource.ResourceLocatorTool;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a
* float array populated from a heightmap generated from an Image. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ImageMapTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ImageMapTerrainExample.jpg", //
maxHeapMemory = 128)
public class ImageMapTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Mesh arrow = new Box("normal", new Vector3(-0.2, -0.2, 0), new Vector3(0.2, 0.2, 4));
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
private double counter = 0;
private int frames = 0;
public static void main(final String[] args) {
ExampleBase.start(ImageMapTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = frames / counter;
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
final Vector3 intersectionNormal = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionNormal(0);
final Matrix3 rotation = new Matrix3();
rotation.lookAt(intersectionNormal, Vector3.UNIT_Z);
arrow.setRotation(rotation);
arrow.setTranslation(intersectionPoint);
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
arrow.getSceneHints().setAllPickingHints(false);
arrow.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(arrow);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
// IMAGE LOADING AND CONVERSION TO HEIGHTMAP DONE HERE
final BufferedImage logo = ImageIO.read(ResourceLocatorTool.getClassPathResource(
ImageMapTerrainExample.class, "com/ardor3d/example/media/images/water/dudvmap.png"));
final Image ardorImage = AWTImageLoader.makeArdor3dImage(logo, false);
final float[] heightMap = ImageHeightMap.generateHeightMap(ardorImage, 0.1f, .3f);
// END OF IMAGE CONVERSION
final int SIZE = ardorImage.getWidth();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
3, 50, 3));
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
arrow.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
arrow.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() + 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() - 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.awt.image.BufferedImage;
import java.util.concurrent.Callable;
import javax.imageio.ImageIO;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.heightmap.ImageHeightMap;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Image;
import com.ardor3d.image.util.awt.AWTImageLoader;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.resource.ResourceLocatorTool;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a
* float array populated from a heightmap generated from an Image. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ImageMapTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ImageMapTerrainExample.jpg", //
maxHeapMemory = 128)
public class ImageMapTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Mesh arrow = new Box("normal", new Vector3(-0.2, -0.2, 0), new Vector3(0.2, 0.2, 4));
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
private double counter = 0;
private int frames = 0;
public static void main(final String[] args) {
ExampleBase.start(ImageMapTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = frames / counter;
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
final Vector3 intersectionNormal = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionNormal(0);
final Matrix3 rotation = new Matrix3();
rotation.lookAt(intersectionNormal, Vector3.UNIT_Z);
arrow.setRotation(rotation);
arrow.setTranslation(intersectionPoint);
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
arrow.getSceneHints().setAllPickingHints(false);
arrow.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(arrow);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
// IMAGE LOADING AND CONVERSION TO HEIGHTMAP DONE HERE
final BufferedImage logo = ImageIO.read(ResourceLocatorTool.getClassPathResource(
ImageMapTerrainExample.class, "com/ardor3d/example/media/images/water/dudvmap.png"));
final Image ardorImage = AWTImageLoader.makeArdor3dImage(logo, false);
final float[] heightMap = ImageHeightMap.generateHeightMap(ardorImage, 0.1f, .3f);
// END OF IMAGE CONVERSION
final int SIZE = ardorImage.getWidth();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
3, 50, 3));
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
arrow.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
arrow.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() + 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() - 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/InMemoryTerrainExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/InMemoryTerrainExample.java index 531ffd4..d1de7d6 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/InMemoryTerrainExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/InMemoryTerrainExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.providers.inmemory.InMemoryTerrainDataProvider;
import com.ardor3d.extension.terrain.providers.inmemory.data.InMemoryTerrainData;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' streaming from an in-memory data source.
* Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.InMemoryTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_InMemoryTerrainExample.jpg", //
maxHeapMemory = 128)
public class InMemoryTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
private Skybox skybox;
private InMemoryTerrainData inMemoryTerrainData;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[6];
public static void main(final String[] args) {
ExampleBase.start(InMemoryTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
skybox.setTranslation(camera.getLocation());
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
inMemoryTerrainData = new InMemoryTerrainData(2048, 9, 128, new Vector3(1, 200, 1));
final TerrainDataProvider terrainDataProvider = new InMemoryTerrainDataProvider(inMemoryTerrainData, true);
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
skybox = buildSkyBox();
skybox.getSceneHints().setAllPickingHints(false);
_root.attachChild(skybox);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (!inMemoryTerrainData.isRunning()) {
inMemoryTerrainData.startUpdates();
} else {
inMemoryTerrainData.stopUpdates();
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() + 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() - 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Builds the sky box.
*/
private Skybox buildSkyBox() {
final Skybox skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
return skybox;
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
_exampleInfo[5].setText("[V] Updating terrain data: " + inMemoryTerrainData.isRunning());
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.providers.inmemory.InMemoryTerrainDataProvider;
import com.ardor3d.extension.terrain.providers.inmemory.data.InMemoryTerrainData;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' streaming from an in-memory data source.
* Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.InMemoryTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_InMemoryTerrainExample.jpg", //
maxHeapMemory = 128)
public class InMemoryTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
private Skybox skybox;
private InMemoryTerrainData inMemoryTerrainData;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[6];
public static void main(final String[] args) {
ExampleBase.start(InMemoryTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
skybox.setTranslation(camera.getLocation());
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
inMemoryTerrainData = new InMemoryTerrainData(2048, 9, 128, new Vector3(1, 200, 1));
final TerrainDataProvider terrainDataProvider = new InMemoryTerrainDataProvider(inMemoryTerrainData, true);
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
skybox = buildSkyBox();
skybox.getSceneHints().setAllPickingHints(false);
_root.attachChild(skybox);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (!inMemoryTerrainData.isRunning()) {
inMemoryTerrainData.startUpdates();
} else {
inMemoryTerrainData.stopUpdates();
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() + 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() - 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Builds the sky box.
*/
private Skybox buildSkyBox() {
final Skybox skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
return skybox;
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
_exampleInfo[5].setText("[V] Updating terrain data: " + inMemoryTerrainData.isRunning());
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/MountainShadowTerrainExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/MountainShadowTerrainExample.java index d25912d..3f1efd2 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/MountainShadowTerrainExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/MountainShadowTerrainExample.java @@ -1 +1,460 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.EnumSet;
import java.util.concurrent.Callable;
import javax.imageio.ImageIO;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.model.collada.jdom.ColladaImporter;
import com.ardor3d.extension.model.collada.jdom.data.ColladaStorage;
import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass;
import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass.Filter;
import com.ardor3d.extension.shadow.map.ShadowCasterManager;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.UrlInputSupplier;
import com.ardor3d.extension.terrain.heightmap.ImageHeightMap;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.extension.ui.Orientation;
import com.ardor3d.extension.ui.UIButton;
import com.ardor3d.extension.ui.UIFrame;
import com.ardor3d.extension.ui.UIFrame.FrameButtons;
import com.ardor3d.extension.ui.UIHud;
import com.ardor3d.extension.ui.UILabel;
import com.ardor3d.extension.ui.UIPanel;
import com.ardor3d.extension.ui.UISlider;
import com.ardor3d.extension.ui.event.ActionEvent;
import com.ardor3d.extension.ui.event.ActionListener;
import com.ardor3d.extension.ui.layout.RowLayout;
import com.ardor3d.extension.ui.text.StyleConstants;
import com.ardor3d.extension.ui.util.Insets;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Image;
import com.ardor3d.image.Texture;
import com.ardor3d.image.Texture2D;
import com.ardor3d.image.util.awt.AWTImageLoader;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.MathUtils;
import com.ardor3d.math.Quaternion;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.renderer.state.RenderState.StateType;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.renderer.state.ZBufferState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.hint.TextureCombineMode;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.geom.Debugger;
import com.ardor3d.util.resource.ResourceLocatorTool;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a
* float array populated from a heightmap generated from an Image. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ImageMapTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ImageMapTerrainExample.jpg", //
maxHeapMemory = 128)
public class MountainShadowTerrainExample extends ExampleBase {
private final float farPlane = 8000.0f;
/** Quads used for debug showing shadowmaps. */
private Quad _orthoQuad[];
private Terrain terrain;
private final Node terrainNode = new Node("terrain");
private boolean groundCamera = false;
private Camera terrainCamera;
/** Text fields used to present info about the example. */
private final UILabel _exampleInfo[] = new UILabel[2];
/** Pssm shadow map pass. */
private ParallelSplitShadowMapPass _pssmPass;
private DirectionalLight light;
private double lightTime;
private boolean moveLight = false;
private UIHud hud;
public static void main(final String[] args) {
ExampleBase._minDepthBits = 24;
ExampleBase.start(MountainShadowTerrainExample.class);
}
@Override
protected void renderExample(final Renderer renderer) {
// Lazy init since it needs the renderer...
if (!_pssmPass.isInitialised()) {
_pssmPass.init(renderer);
_pssmPass.setPssmShader(terrain.getGeometryClipmapShader());
for (int i = 0; i < _pssmPass.getNumOfSplits(); i++) {
terrain.getClipTextureState().setTexture(_pssmPass.getShadowMapTexture(i), i + 1);
}
for (int i = 0; i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) {
terrain.getGeometryClipmapShader().setUniform("shadowMap" + i, i + 1);
}
}
terrain.getGeometryClipmapShader().setUniform("lightDir", light.getDirection());
for (int i = 0; i < _pssmPass.getNumOfSplits(); i++) {
TextureState screen = (TextureState) _orthoQuad[i].getLocalRenderState(StateType.Texture);
Texture copy;
if (screen == null) {
screen = new TextureState();
_orthoQuad[i].setRenderState(screen);
copy = new Texture2D();
screen.setTexture(copy);
_orthoQuad[i].updateGeometricState(0.0);
} else {
copy = screen.getTexture();
}
copy.setTextureKey(_pssmPass.getShadowMapTexture(i).getTextureKey());
}
// XXX: Use a rougher LOD for shadows - tweak?
terrain.setMinVisibleLevel(4);
// Update shadowmaps - this will update our terrain camera to light pos
_pssmPass.updateShadowMaps(renderer);
// XXX: reset LOD for drawing from view camera
terrain.setMinVisibleLevel(0);
// Render scene and terrain with shadows
terrainNode.onDraw(renderer);
_root.onDraw(renderer);
// Render overlay shadows for all objects except the terrain
renderer.renderBuckets();
_pssmPass.renderShadowedScene(renderer);
renderer.renderBuckets();
// draw ui
renderer.draw(hud);
}
private double counter = 0;
private int frames = 0;
@Override
protected void updateExample(final ReadOnlyTimer timer) {
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = frames / counter;
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
terrainCamera.set(camera);
} else {
terrainCamera.set(_canvas.getCanvasRenderer().getCamera());
}
// move terrain to view pos
terrainNode.updateGeometricState(timer.getTimePerFrame());
hud.updateGeometricState(timer.getTimePerFrame());
if (moveLight) {
lightTime += timer.getTimePerFrame();
light.setDirection(new Vector3(Math.sin(lightTime), -.8, Math.cos(lightTime)).normalizeLocal());
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain Example");
final Camera canvasCamera = _canvas.getCanvasRenderer().getCamera();
canvasCamera.setLocation(new Vector3(2176, 790, 688));
canvasCamera.lookAt(new Vector3(canvasCamera.getLocation()).addLocal(-0.87105768019686, -0.4349655341112313,
0.22817427967541867), Vector3.UNIT_Y);
canvasCamera.setFrustumPerspective(45.0, (float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.BLUE);
return null;
}
});
_controlHandle.setMoveSpeed(400);
setupDefaultStates();
addRover();
addUI();
// Initialize PSSM shadows
_pssmPass = new ParallelSplitShadowMapPass(light, 2048, 4);
_pssmPass.setFiltering(Filter.None);
_pssmPass.setRenderShadowedScene(false);
_pssmPass.setKeepMainShader(true);
// _pssmPass.setMinimumLightDistance(500); // XXX: Tune this
_pssmPass.setUseSceneTexturing(false);
_pssmPass.setUseObjectCullFace(false);
_pssmPass.getShadowOffsetState().setFactor(1.1f);
_pssmPass.getShadowOffsetState().setUnits(4.0f);
// _pssmPass.setDrawDebug(true);
// TODO: backside lock test
final Quad floor = new Quad("floor", 2048, 2048);
floor.updateModelBound();
floor.setRotation(new Quaternion().fromAngleAxis(MathUtils.HALF_PI, Vector3.UNIT_X));
floor.setTranslation(1024, 0, 1024);
terrainNode.attachChild(floor);
_pssmPass.addBoundsReceiver(terrainNode);
// Add objects that will get shadowed through overlay render
_pssmPass.add(_root);
// Add our occluders that will produce shadows
ShadowCasterManager.INSTANCE.addSpatial(terrainNode);
ShadowCasterManager.INSTANCE.addSpatial(_root);
final int quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
_orthoQuad = new Quad[ParallelSplitShadowMapPass._MAX_SPLITS];
for (int i = 0; i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) {
_orthoQuad[i] = new Quad("OrthoQuad", quadSize, quadSize);
_orthoQuad[i].setTranslation(new Vector3(quadSize / 2 + 5 + (quadSize + 5) * i, quadSize / 2 + 5, 1));
_orthoQuad[i].setScale(1, -1, 1);
_orthoQuad[i].getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
_orthoQuad[i].getSceneHints().setLightCombineMode(LightCombineMode.Off);
_orthoQuad[i].getSceneHints().setTextureCombineMode(TextureCombineMode.Replace);
_orthoQuad[i].getSceneHints().setCullHint(CullHint.Never);
hud.attachChild(_orthoQuad[i]);
}
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
// IMAGE LOADING AND CONVERSION TO HEIGHTMAP DONE HERE
final BufferedImage heightmap = ImageIO.read(ResourceLocatorTool.getClassPathResource(
MountainShadowTerrainExample.class, "com/ardor3d/example/media/images/heightmap.jpg"));
final Image ardorImage = AWTImageLoader.makeArdor3dImage(heightmap, false);
final float[] heightMap = ImageHeightMap.generateHeightMap(ardorImage, 0.05f, .33f);
// END OF IMAGE CONVERSION
final int SIZE = ardorImage.getWidth();
final ArrayTerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE,
new Vector3(5, 2048, 5), true);
terrainDataProvider.setHeightMax(0.34f);
final TerrainBuilder builder = new TerrainBuilder(terrainDataProvider, terrainCamera)
.setShowDebugPanels(true);
terrain = builder.build();
terrain.setPixelShader(new UrlInputSupplier(ResourceLocatorTool.getClassPathResource(
ShadowedTerrainExample.class,
"com/ardor3d/extension/terrain/shadowedGeometryClipmapShader_normalMap.frag")));
terrain.reloadShader();
terrain.getGeometryClipmapShader().setUniform("normalMap", 5);
terrainNode.attachChild(terrain);
terrain.setCullingEnabled(false);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = new UILabel("Text");
_exampleInfo[i].setForegroundColor(ColorRGBA.WHITE, true);
_exampleInfo[i].addFontStyle(StyleConstants.KEY_SIZE, 16);
_exampleInfo[i].addFontStyle(StyleConstants.KEY_BOLD, Boolean.TRUE);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
hud.add(_exampleInfo[i]);
}
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
}
private void addRover() {
try {
final ColladaStorage storage = new ColladaImporter().load("collada/sketchup/NASA Mars Rover.dae");
final Node rover = storage.getScene();
rover.setTranslation(440, 102, 160.1);
rover.setScale(3);
rover.setRotation(new Quaternion().fromAngleAxis(-MathUtils.HALF_PI, Vector3.UNIT_X));
_root.attachChild(rover);
} catch (final IOException ex) {
ex.printStackTrace();
}
}
private void setupDefaultStates() {
terrainNode.setRenderState(_lightState);
terrainNode.setRenderState(_wireframeState);
terrainNode.setRenderState(new ZBufferState());
_lightState.detachAll();
light = new DirectionalLight();
light.setEnabled(true);
light.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
light.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
light.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
light.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(light);
_lightState.setEnabled(true);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
terrainNode.setRenderState(fs);
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3/4] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
}
@Override
protected void updateLogicalLayer(final ReadOnlyTimer timer) {
hud.getLogicalLayer().checkTriggers(timer.getTimePerFrame());
}
@Override
protected void renderDebug(final Renderer renderer) {
super.renderDebug(renderer);
if (_showBounds) {
Debugger.drawBounds(terrainNode, renderer, true);
}
}
private void addUI() {
// setup hud
hud = new UIHud();
hud.setupInput(_canvas, _physicalLayer, _logicalLayer);
hud.setMouseManager(_mouseManager);
final UIFrame frame = new UIFrame("Controls", EnumSet.noneOf(FrameButtons.class));
frame.setResizeable(false);
final UILabel distLabel = new UILabel("Max Shadow Distance: 1500");
final UISlider distSlider = new UISlider(Orientation.Horizontal, 0, 2000, 1500);
distSlider.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
_pssmPass.setMaxShadowDistance(distSlider.getValue());
distLabel.setText("Max Shadow Distance: " + distSlider.getValue());
}
});
final UIButton updateCamera = new UIButton("Update Shadow Camera");
updateCamera.setSelectable(true);
updateCamera.setSelected(true);
updateCamera.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
_pssmPass.setUpdateMainCamera(updateCamera.isSelected());
updateText();
}
});
final UIButton rotateLight = new UIButton("Rotate Light");
rotateLight.setSelectable(true);
rotateLight.setSelected(false);
rotateLight.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
moveLight = rotateLight.isSelected();
updateText();
}
});
final UIPanel panel = new UIPanel(new RowLayout(false, true, false));
panel.setPadding(new Insets(10, 20, 10, 20));
panel.add(distLabel);
panel.add(distSlider);
panel.add(updateCamera);
panel.add(rotateLight);
frame.setContentPanel(panel);
frame.pack();
final Camera cam = _canvas.getCanvasRenderer().getCamera();
frame.setLocalXY(cam.getWidth() - frame.getLocalComponentWidth(),
cam.getHeight() - frame.getLocalComponentHeight());
hud.add(frame);
}
}
\ No newline at end of file +/** + * Copyright (c) 2008-2018 Ardor Labs, Inc. + * + * This file is part of Ardor3D. + * + * Ardor3D is free software: you can redistribute it and/or modify it + * under the terms of its license which may be found in the accompanying + * LICENSE file or at <http://www.ardor3d.com/LICENSE>. + */ + +package com.ardor3d.example.terrain; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.EnumSet; +import java.util.concurrent.Callable; + +import javax.imageio.ImageIO; + +import com.ardor3d.example.ExampleBase; +import com.ardor3d.example.Purpose; +import com.ardor3d.extension.model.collada.jdom.ColladaImporter; +import com.ardor3d.extension.model.collada.jdom.data.ColladaStorage; +import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass; +import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass.Filter; +import com.ardor3d.extension.shadow.map.ShadowCasterManager; +import com.ardor3d.extension.terrain.client.Terrain; +import com.ardor3d.extension.terrain.client.TerrainBuilder; +import com.ardor3d.extension.terrain.client.UrlInputSupplier; +import com.ardor3d.extension.terrain.heightmap.ImageHeightMap; +import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider; +import com.ardor3d.extension.ui.Orientation; +import com.ardor3d.extension.ui.UIButton; +import com.ardor3d.extension.ui.UIFrame; +import com.ardor3d.extension.ui.UIFrame.FrameButtons; +import com.ardor3d.extension.ui.UIHud; +import com.ardor3d.extension.ui.UILabel; +import com.ardor3d.extension.ui.UIPanel; +import com.ardor3d.extension.ui.UISlider; +import com.ardor3d.extension.ui.event.ActionEvent; +import com.ardor3d.extension.ui.event.ActionListener; +import com.ardor3d.extension.ui.layout.RowLayout; +import com.ardor3d.extension.ui.text.StyleConstants; +import com.ardor3d.extension.ui.util.Insets; +import com.ardor3d.framework.Canvas; +import com.ardor3d.framework.CanvasRenderer; +import com.ardor3d.image.Image; +import com.ardor3d.image.Texture; +import com.ardor3d.image.Texture2D; +import com.ardor3d.image.util.awt.AWTImageLoader; +import com.ardor3d.input.Key; +import com.ardor3d.input.logical.InputTrigger; +import com.ardor3d.input.logical.KeyPressedCondition; +import com.ardor3d.input.logical.TriggerAction; +import com.ardor3d.input.logical.TwoInputStates; +import com.ardor3d.light.DirectionalLight; +import com.ardor3d.math.ColorRGBA; +import com.ardor3d.math.MathUtils; +import com.ardor3d.math.Quaternion; +import com.ardor3d.math.Vector3; +import com.ardor3d.renderer.Camera; +import com.ardor3d.renderer.RenderContext; +import com.ardor3d.renderer.Renderer; +import com.ardor3d.renderer.queue.RenderBucketType; +import com.ardor3d.renderer.state.FogState; +import com.ardor3d.renderer.state.FogState.DensityFunction; +import com.ardor3d.renderer.state.RenderState.StateType; +import com.ardor3d.renderer.state.TextureState; +import com.ardor3d.renderer.state.ZBufferState; +import com.ardor3d.scenegraph.Node; +import com.ardor3d.scenegraph.hint.CullHint; +import com.ardor3d.scenegraph.hint.LightCombineMode; +import com.ardor3d.scenegraph.hint.TextureCombineMode; +import com.ardor3d.scenegraph.shape.Quad; +import com.ardor3d.util.GameTaskQueue; +import com.ardor3d.util.GameTaskQueueManager; +import com.ardor3d.util.ReadOnlyTimer; +import com.ardor3d.util.geom.Debugger; +import com.ardor3d.util.resource.ResourceLocatorTool; + +/** + * Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a + * float array populated from a heightmap generated from an Image. Requires GLSL support. + */ +@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.MountainShadowTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_MountainShadowTerrainExample.jpg", //
maxHeapMemory = 128) +public class MountainShadowTerrainExample extends ExampleBase { + + private final float farPlane = 8000.0f; + + /** Quads used for debug showing shadowmaps. */ + private Quad _orthoQuad[]; + + private Terrain terrain; + private final Node terrainNode = new Node("terrain"); + + private boolean groundCamera = false; + private Camera terrainCamera; + + /** Text fields used to present info about the example. */ + private final UILabel _exampleInfo[] = new UILabel[2]; + + /** Pssm shadow map pass. */ + private ParallelSplitShadowMapPass _pssmPass; + + private DirectionalLight directionalLight;
+ private double lightTime; + private boolean moveLight = false; + + private UIHud hud; + + public static void main(final String[] args) { + ExampleBase._minDepthBits = 24; + ExampleBase.start(MountainShadowTerrainExample.class); + } + + @Override + protected void renderExample(final Renderer renderer) { + // Lazy init since it needs the renderer... + if (!_pssmPass.isInitialised()) { + _pssmPass.init(renderer); + _pssmPass.setPssmShader(terrain.getGeometryClipmapShader()); + for (int i = 0; i < _pssmPass.getNumOfSplits(); i++) { + terrain.getClipTextureState().setTexture(_pssmPass.getShadowMapTexture(i), i + 1); + } + for (int i = 0; i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) { + terrain.getGeometryClipmapShader().setUniform("shadowMap" + i, i + 1); + } + } + + terrain.getGeometryClipmapShader().setUniform("lightDir", directionalLight.getDirection());
+ for (int i = 0; i < _pssmPass.getNumOfSplits(); i++) { + TextureState screen = (TextureState) _orthoQuad[i].getLocalRenderState(StateType.Texture); + Texture copy; + if (screen == null) { + screen = new TextureState(); + _orthoQuad[i].setRenderState(screen); + copy = new Texture2D(); + screen.setTexture(copy); + _orthoQuad[i].updateGeometricState(0.0); + } else { + copy = screen.getTexture(); + } + copy.setTextureKey(_pssmPass.getShadowMapTexture(i).getTextureKey()); + } + + // XXX: Use a rougher LOD for shadows - tweak? + terrain.setMinVisibleLevel(4); + + // Update shadowmaps - this will update our terrain camera to light pos + _pssmPass.updateShadowMaps(renderer); + + // XXX: reset LOD for drawing from view camera + terrain.setMinVisibleLevel(0); + + // Render scene and terrain with shadows + terrainNode.onDraw(renderer); + _root.onDraw(renderer); + + // Render overlay shadows for all objects except the terrain + renderer.renderBuckets(); + _pssmPass.renderShadowedScene(renderer); + renderer.renderBuckets(); + + // draw ui + renderer.draw(hud); + } + + private double counter = 0; + private int frames = 0; + + @Override + protected void updateExample(final ReadOnlyTimer timer) { + counter += timer.getTimePerFrame(); + frames++; + if (counter > 1) { + final double fps = frames / counter; + counter = 0; + frames = 0; + System.out.printf("%7.1f FPS\n", fps); + } + + final Camera camera = _canvas.getCanvasRenderer().getCamera(); + + // Make sure camera is above terrain + final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ()); + if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) { + camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ())); + terrainCamera.set(camera); + } else { + terrainCamera.set(_canvas.getCanvasRenderer().getCamera()); + } + + // move terrain to view pos + terrainNode.updateGeometricState(timer.getTimePerFrame()); + hud.updateGeometricState(timer.getTimePerFrame()); + + if (moveLight) { + lightTime += timer.getTimePerFrame(); + directionalLight.setDirection(new Vector3(Math.sin(lightTime), -.8, Math.cos(lightTime)).normalizeLocal());
} + } + + /** + * Initialize pssm pass and scene. + */ + @Override + protected void initExample() { + // Setup main camera. + _canvas.setTitle("Terrain Example"); + final Camera canvasCamera = _canvas.getCanvasRenderer().getCamera(); + canvasCamera.setLocation(new Vector3(2176, 790, 688)); + canvasCamera.lookAt(new Vector3(canvasCamera.getLocation()).addLocal(-0.87105768019686, -0.4349655341112313, + 0.22817427967541867), Vector3.UNIT_Y); + canvasCamera.setFrustumPerspective(45.0, (float) _canvas.getCanvasRenderer().getCamera().getWidth() + / _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane); + final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer(); + final RenderContext renderContext = canvasRenderer.getRenderContext(); + final Renderer renderer = canvasRenderer.getRenderer(); + GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() { + @Override + public Void call() throws Exception { + renderer.setBackgroundColor(ColorRGBA.BLUE); + return null; + } + }); + _controlHandle.setMoveSpeed(400); + + setupDefaultStates(); + addRover(); + addUI(); + + // Initialize PSSM shadows + _pssmPass = new ParallelSplitShadowMapPass(directionalLight, 2048, 4);
_pssmPass.setFiltering(Filter.None); + _pssmPass.setRenderShadowedScene(false); + _pssmPass.setKeepMainShader(true); + // _pssmPass.setMinimumLightDistance(500); // XXX: Tune this + _pssmPass.setUseSceneTexturing(false); + _pssmPass.setUseObjectCullFace(false); + _pssmPass.getShadowOffsetState().setFactor(1.1f); + _pssmPass.getShadowOffsetState().setUnits(4.0f); + // _pssmPass.setDrawDebug(true); + + // TODO: backside lock test + final Quad floor = new Quad("floor", 2048, 2048); + floor.updateModelBound(); + floor.setRotation(new Quaternion().fromAngleAxis(MathUtils.HALF_PI, Vector3.UNIT_X)); + floor.setTranslation(1024, 0, 1024); + terrainNode.attachChild(floor); + + _pssmPass.addBoundsReceiver(terrainNode); + + // Add objects that will get shadowed through overlay render + _pssmPass.add(_root); + + // Add our occluders that will produce shadows + ShadowCasterManager.INSTANCE.addSpatial(terrainNode); + ShadowCasterManager.INSTANCE.addSpatial(_root); + + final int quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10; + _orthoQuad = new Quad[ParallelSplitShadowMapPass._MAX_SPLITS]; + for (int i = 0; i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) { + _orthoQuad[i] = new Quad("OrthoQuad", quadSize, quadSize); + _orthoQuad[i].setTranslation(new Vector3(quadSize / 2 + 5 + (quadSize + 5) * i, quadSize / 2 + 5, 1)); + _orthoQuad[i].setScale(1, -1, 1); + _orthoQuad[i].getSceneHints().setRenderBucketType(RenderBucketType.Ortho); + _orthoQuad[i].getSceneHints().setLightCombineMode(LightCombineMode.Off); + _orthoQuad[i].getSceneHints().setTextureCombineMode(TextureCombineMode.Replace); + _orthoQuad[i].getSceneHints().setCullHint(CullHint.Never); + hud.attachChild(_orthoQuad[i]); + } + + try { + // Keep a separate camera to be able to freeze terrain update + final Camera camera = _canvas.getCanvasRenderer().getCamera(); + terrainCamera = new Camera(camera); + + // IMAGE LOADING AND CONVERSION TO HEIGHTMAP DONE HERE + final BufferedImage heightmap = ImageIO.read(ResourceLocatorTool.getClassPathResource( + MountainShadowTerrainExample.class, "com/ardor3d/example/media/images/heightmap.jpg")); + final Image ardorImage = AWTImageLoader.makeArdor3dImage(heightmap, false); + final float[] heightMap = ImageHeightMap.generateHeightMap(ardorImage, 0.05f, .33f); + // END OF IMAGE CONVERSION + + final int SIZE = ardorImage.getWidth(); + + final ArrayTerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, + new Vector3(5, 2048, 5), true); + terrainDataProvider.setHeightMax(0.34f); + + final TerrainBuilder builder = new TerrainBuilder(terrainDataProvider, terrainCamera) + .setShowDebugPanels(true); + + terrain = builder.build(); + terrain.setPixelShader(new UrlInputSupplier(ResourceLocatorTool.getClassPathResource(
ShadowedTerrainExample.class,
"com/ardor3d/extension/terrain/shadowedGeometryClipmapShader_normalMap.frag"))); + terrain.reloadShader(); + terrain.getGeometryClipmapShader().setUniform("normalMap", 5); + terrainNode.attachChild(terrain); + + terrain.setCullingEnabled(false); + } catch (final Exception ex1) { + System.out.println("Problem setting up terrain..."); + ex1.printStackTrace(); + } + + final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2; + for (int i = 0; i < _exampleInfo.length; i++) { + _exampleInfo[i] = new UILabel("Text"); + _exampleInfo[i].setForegroundColor(ColorRGBA.WHITE, true); + _exampleInfo[i].addFontStyle(StyleConstants.KEY_SIZE, 16); + _exampleInfo[i].addFontStyle(StyleConstants.KEY_BOLD, Boolean.TRUE); + _exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0)); + hud.add(_exampleInfo[i]); + } + + updateText(); + + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() { + @Override + public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _controlHandle.setMoveSpeed(5); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() { + @Override + public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _controlHandle.setMoveSpeed(50); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() { + @Override + public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _controlHandle.setMoveSpeed(400); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() { + @Override + public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _controlHandle.setMoveSpeed(1000); + updateText(); + } + })); + + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override + public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + groundCamera = !groundCamera; + updateText(); + } + })); + } + + private void addRover() { + try { + final ColladaStorage storage = new ColladaImporter().load("collada/sketchup/NASA Mars Rover.dae"); + final Node rover = storage.getScene(); + rover.setTranslation(440, 102, 160.1); + rover.setScale(3); + rover.setRotation(new Quaternion().fromAngleAxis(-MathUtils.HALF_PI, Vector3.UNIT_X)); + _root.attachChild(rover); + } catch (final IOException ex) { + ex.printStackTrace(); + } + + } + + private void setupDefaultStates() { + terrainNode.setRenderState(_lightState); + terrainNode.setRenderState(_wireframeState); + terrainNode.setRenderState(new ZBufferState()); + + _lightState.detachAll(); + directionalLight = new DirectionalLight();
directionalLight.setEnabled(true);
directionalLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
directionalLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
directionalLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
directionalLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(directionalLight);
_lightState.setEnabled(true); + + final FogState fs = new FogState(); + fs.setStart(farPlane / 2.0f); + fs.setEnd(farPlane); + fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); + fs.setDensityFunction(DensityFunction.Linear); + terrainNode.setRenderState(fs); + } + + /** + * Update text information. + */ + private void updateText() { + _exampleInfo[0].setText("[1/2/3/4] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h"); + _exampleInfo[1].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly")); + } + + @Override + protected void updateLogicalLayer(final ReadOnlyTimer timer) { + hud.getLogicalLayer().checkTriggers(timer.getTimePerFrame()); + } + + @Override + protected void renderDebug(final Renderer renderer) { + super.renderDebug(renderer); + if (_showBounds) { + Debugger.drawBounds(terrainNode, renderer, true); + } + } + + private void addUI() { + // setup hud + hud = new UIHud(); + hud.setupInput(_canvas, _physicalLayer, _logicalLayer); + hud.setMouseManager(_mouseManager); + + final UIFrame frame = new UIFrame("Controls", EnumSet.noneOf(FrameButtons.class)); + frame.setResizeable(false); + + final UILabel distLabel = new UILabel("Max Shadow Distance: 1500"); + final UISlider distSlider = new UISlider(Orientation.Horizontal, 0, 2000, 1500); + distSlider.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent event) { + _pssmPass.setMaxShadowDistance(distSlider.getValue()); + distLabel.setText("Max Shadow Distance: " + distSlider.getValue()); + } + }); + + final UIButton updateCamera = new UIButton("Update Shadow Camera"); + updateCamera.setSelectable(true); + updateCamera.setSelected(true); + updateCamera.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent event) { + _pssmPass.setUpdateMainCamera(updateCamera.isSelected()); + updateText(); + } + }); + + final UIButton rotateLight = new UIButton("Rotate Light"); + rotateLight.setSelectable(true); + rotateLight.setSelected(false); + rotateLight.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent event) { + moveLight = rotateLight.isSelected(); + updateText(); + } + }); + + final UIPanel panel = new UIPanel(new RowLayout(false, true, false)); + panel.setPadding(new Insets(10, 20, 10, 20)); + panel.add(distLabel); + panel.add(distSlider); + panel.add(updateCamera); + panel.add(rotateLight); + + frame.setContentPanel(panel); + frame.pack(); + final Camera cam = _canvas.getCanvasRenderer().getCamera(); + frame.setLocalXY(cam.getWidth() - frame.getLocalComponentWidth(), + cam.getHeight() - frame.getLocalComponentHeight()); + hud.add(frame); + } +} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ProceduralTerrainExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ProceduralTerrainExample.java index 0483945..a647485 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ProceduralTerrainExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ProceduralTerrainExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.providers.procedural.ProceduralTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.functions.FbmFunction3D;
import com.ardor3d.math.functions.Function3D;
import com.ardor3d.math.functions.Functions;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' using content procedurally generated
* on-the-fly. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ProceduralTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ProceduralTerrainExample.jpg", //
maxHeapMemory = 64)
public class ProceduralTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
private Skybox skybox;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
public static void main(final String[] args) {
ExampleBase.start(ProceduralTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
skybox.setTranslation(camera.getLocation());
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Procedural Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.BLUE);
return null;
}
});
_controlHandle.setMoveSpeed(50);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
final double scale = 1.0 / 4000.0;
Function3D functionTmp = new FbmFunction3D(Functions.simplexNoise(), 9, 0.5, 0.5, 3.14);
functionTmp = Functions.clamp(functionTmp, -1.2, 1.2);
final Function3D function = Functions.scaleInput(functionTmp, scale, scale, 1);
final TerrainDataProvider terrainDataProvider = new ProceduralTerrainDataProvider(function, new Vector3(1,
200, 1), -1.2f, 1.2f);
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
skybox = buildSkyBox();
skybox.getSceneHints().setAllPickingHints(false);
_root.attachChild(skybox);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(200);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(500);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(-5000, 500, -5000);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(5000, 500, 5000);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Builds the sky box.
*/
private Skybox buildSkyBox() {
final Skybox skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
return skybox;
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3/4] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.providers.procedural.ProceduralTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.functions.FbmFunction3D;
import com.ardor3d.math.functions.Function3D;
import com.ardor3d.math.functions.Functions;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' using content procedurally generated
* on-the-fly. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ProceduralTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ProceduralTerrainExample.jpg", //
maxHeapMemory = 64)
public class ProceduralTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
private Skybox skybox;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
public static void main(final String[] args) {
ExampleBase.start(ProceduralTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
skybox.setTranslation(camera.getLocation());
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Procedural Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.BLUE);
return null;
}
});
_controlHandle.setMoveSpeed(50);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
final double scale = 1.0 / 4000.0;
Function3D functionTmp = new FbmFunction3D(Functions.simplexNoise(), 9, 0.5, 0.5, 3.14);
functionTmp = Functions.clamp(functionTmp, -1.2, 1.2);
final Function3D function = Functions.scaleInput(functionTmp, scale, scale, 1);
final TerrainDataProvider terrainDataProvider = new ProceduralTerrainDataProvider(function, new Vector3(1,
200, 1), -1.2f, 1.2f);
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
skybox = buildSkyBox();
skybox.getSceneHints().setAllPickingHints(false);
_root.attachChild(skybox);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(200);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(500);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(-5000, 500, -5000);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(5000, 500, 5000);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Builds the sky box.
*/
private Skybox buildSkyBox() {
final Skybox skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
return skybox;
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3/4] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ShadowedTerrainExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ShadowedTerrainExample.java index 1a895ad..1c7766e 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ShadowedTerrainExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ShadowedTerrainExample.java @@ -1 +1,384 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.ardor3d.bounding.BoundingBox;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass;
import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass.Filter;
import com.ardor3d.extension.shadow.map.ShadowCasterManager;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.client.UrlInputSupplier;
import com.ardor3d.extension.terrain.heightmap.MidPointHeightMapGenerator;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.resource.ResourceLocatorTool;
/**
* Example showing the Geometry Clipmap Terrain system combined with PSSM. (a bit experimental) Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ShadowedTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ShadowedTerrainExample.jpg", //
maxHeapMemory = 128)
public class ShadowedTerrainExample extends ExampleBase {
/** The Constant logger. */
private static final Logger logger = Logger.getLogger(ShadowedTerrainExample.class.getName());
private boolean updateTerrain = true;
private final float farPlane = 2500.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
/** Pssm shadow map pass. */
private ParallelSplitShadowMapPass _pssmPass;
private DirectionalLight light;
/** Temp vec for updating light pos. */
private final Vector3 lightPosition = new Vector3(10000, 10000, 10000);
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
public static void main(final String[] args) {
ExampleBase.start(ShadowedTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
}
@Override
protected void renderExample(final Renderer renderer) {
// Lazy init since it needs the renderer...
if (!_pssmPass.isInitialised()) {
_pssmPass.init(renderer);
_pssmPass.setPssmShader(terrain.getGeometryClipmapShader());
for (int i = 0; i < _pssmPass.getNumOfSplits(); i++) {
terrain.getClipTextureState().setTexture(_pssmPass.getShadowMapTexture(i), i + 1);
}
for (int i = 0; i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) {
terrain.getGeometryClipmapShader().setUniform("shadowMap" + i, i + 1);
}
}
// Update shadowmaps
_pssmPass.updateShadowMaps(renderer);
// Render scene and terrain with shadows
super.renderExample(renderer);
renderer.renderBuckets();
// Render overlay shadows for all objects except the terrain
_pssmPass.renderShadowedScene(renderer);
// TODO: this results in text etc also being shadowed, since they are drawn in the main render...
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
_canvas.setTitle("Terrain Example");
final Camera cam = _canvas.getCanvasRenderer().getCamera();
cam.setLocation(new Vector3(440, 215, 275));
cam.lookAt(new Vector3(450, 140, 360), Vector3.UNIT_Y);
cam.setFrustumPerspective(70.0, (float) cam.getWidth() / cam.getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
terrainCamera = new Camera(cam);
final int SIZE = 2048;
final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.6f);
raw.setHeightRange(0.2f);
final float[] heightMap = raw.getHeightData();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 300, 1));
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
terrain.setPixelShader(new UrlInputSupplier(ResourceLocatorTool
.getClassPathResource(ShadowedTerrainExample.class,
"com/ardor3d/extension/terrain/shadowedGeometryClipmapShaderPCF.frag")));
terrain.reloadShader();
_root.attachChild(terrain);
} catch (final Exception e) {
logger.log(Level.SEVERE, "Problem setting up terrain...", e);
System.exit(1);
}
// Initialize PSSM shadows
_pssmPass = new ParallelSplitShadowMapPass(light, 1024, 4);
_pssmPass.setFiltering(Filter.Pcf);
_pssmPass.setRenderShadowedScene(false);
_pssmPass.setKeepMainShader(true);
_pssmPass.setMaxShadowDistance(750); // XXX: Tune this
// _pssmPass.setMinimumLightDistance(500); // XXX: Tune this
_pssmPass.setUseSceneTexturing(false);
_pssmPass.setUseObjectCullFace(false);
// _pssmPass.setDrawDebug(true);
final Node occluders = setupOccluders();
_root.attachChild(occluders);
// TODO: could we use the shadow variable in scenehints here??
// Add objects that will get shadowed through overlay render
_pssmPass.add(occluders);
// Add terrain in as bounds receiver as well, since it's not in the overlay list
_pssmPass.addBoundsReceiver(terrain);
// Add our occluders that will produce shadows
ShadowCasterManager.INSTANCE.addSpatial(occluders);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.C), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_pssmPass.setUpdateMainCamera(!_pssmPass.isUpdateMainCamera());
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera cam = _canvas.getCanvasRenderer().getCamera();
System.out.println("camera location: " + cam.getLocation());
System.out.println("camera direction: " + cam.getDirection());
}
}));
}
private Node setupOccluders() {
final Node occluders = new Node("Occluders");
final Box box = new Box("Box", new Vector3(), 1, 40, 1);
box.setModelBound(new BoundingBox());
box.setRandomColors();
final Random rand = new Random(1337);
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
final Mesh sm = box.makeCopy(true);
sm.setTranslation(500 + rand.nextDouble() * 300 - 150, 20 + rand.nextDouble() * 5.0,
500 + rand.nextDouble() * 300 - 150);
occluders.attachChild(sm);
}
}
return occluders;
}
private void setupDefaultStates() {
_lightState.detachAll();
light = new DirectionalLight();
light.setEnabled(true);
light.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
light.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
light.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
light.setDirection(lightPosition.normalize(null).negateLocal());
_lightState.attach(light);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file +/** + * Copyright (c) 2008-2018 Ardor Labs, Inc. + * + * This file is part of Ardor3D. + * + * Ardor3D is free software: you can redistribute it and/or modify it + * under the terms of its license which may be found in the accompanying + * LICENSE file or at <http://www.ardor3d.com/LICENSE>. + */ + +package com.ardor3d.example.terrain; + +import java.util.Random; +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.ardor3d.bounding.BoundingBox; +import com.ardor3d.example.ExampleBase; +import com.ardor3d.example.Purpose; +import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass; +import com.ardor3d.extension.shadow.map.ParallelSplitShadowMapPass.Filter; +import com.ardor3d.extension.shadow.map.ShadowCasterManager; +import com.ardor3d.extension.terrain.client.Terrain; +import com.ardor3d.extension.terrain.client.TerrainBuilder; +import com.ardor3d.extension.terrain.client.TerrainDataProvider; +import com.ardor3d.extension.terrain.client.UrlInputSupplier; +import com.ardor3d.extension.terrain.heightmap.MidPointHeightMapGenerator; +import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider; +import com.ardor3d.framework.Canvas; +import com.ardor3d.framework.CanvasRenderer; +import com.ardor3d.input.Key; +import com.ardor3d.input.logical.InputTrigger; +import com.ardor3d.input.logical.KeyPressedCondition; +import com.ardor3d.input.logical.TriggerAction; +import com.ardor3d.input.logical.TwoInputStates; +import com.ardor3d.intersection.PickingUtil; +import com.ardor3d.intersection.PrimitivePickResults; +import com.ardor3d.light.DirectionalLight; +import com.ardor3d.math.ColorRGBA; +import com.ardor3d.math.Ray3; +import com.ardor3d.math.Vector3; +import com.ardor3d.renderer.Camera; +import com.ardor3d.renderer.RenderContext; +import com.ardor3d.renderer.Renderer; +import com.ardor3d.renderer.queue.RenderBucketType; +import com.ardor3d.renderer.state.CullState; +import com.ardor3d.renderer.state.FogState; +import com.ardor3d.renderer.state.FogState.DensityFunction; +import com.ardor3d.scenegraph.Mesh; +import com.ardor3d.scenegraph.Node; +import com.ardor3d.scenegraph.hint.CullHint; +import com.ardor3d.scenegraph.hint.LightCombineMode; +import com.ardor3d.scenegraph.shape.Box; +import com.ardor3d.scenegraph.shape.Sphere; +import com.ardor3d.ui.text.BasicText; +import com.ardor3d.util.GameTaskQueue; +import com.ardor3d.util.GameTaskQueueManager; +import com.ardor3d.util.ReadOnlyTimer; +import com.ardor3d.util.resource.ResourceLocatorTool; + +/** + * Example showing the Geometry Clipmap Terrain system combined with PSSM. (a bit experimental) Requires GLSL support. + */ +@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ShadowedTerrainExample", // + thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ShadowedTerrainExample.jpg", // + maxHeapMemory = 128) +public class ShadowedTerrainExample extends ExampleBase { + /** The Constant logger. */ + private static final Logger logger = Logger.getLogger(ShadowedTerrainExample.class.getName()); + + private boolean updateTerrain = true; + private final float farPlane = 2500.0f; + + private Terrain terrain; + + private final Sphere sphere = new Sphere("sp", 16, 16, 1); + private final Ray3 pickRay = new Ray3(); + + private boolean groundCamera = false; + private Camera terrainCamera; + + /** Pssm shadow map pass. */ + private ParallelSplitShadowMapPass _pssmPass; + + private DirectionalLight directionalLight;
+ /** Temp vec for updating light pos. */ + private final Vector3 lightPosition = new Vector3(10000, 10000, 10000); + + /** Text fields used to present info about the example. */ + private final BasicText _exampleInfo[] = new BasicText[5]; + + public static void main(final String[] args) { + ExampleBase.start(ShadowedTerrainExample.class); + } + + @Override + protected void updateExample(final ReadOnlyTimer timer) { + final Camera camera = _canvas.getCanvasRenderer().getCamera(); + + // Make sure camera is above terrain + final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ()); + if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) { + camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ())); + } + + if (updateTerrain) { + terrainCamera.set(camera); + } + + // if we're picking... + if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) { + // Set up our pick ray + pickRay.setOrigin(camera.getLocation()); + pickRay.setDirection(camera.getDirection()); + + // do pick and move the sphere + final PrimitivePickResults pickResults = new PrimitivePickResults(); + pickResults.setCheckDistance(true); + PickingUtil.findPick(_root, pickRay, pickResults); + if (pickResults.getNumber() != 0) { + final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord() + .getIntersectionPoint(0); + sphere.setTranslation(intersectionPoint); + // XXX: maybe change the color of the ball for valid vs. invalid? + } + } + } + + @Override + protected void renderExample(final Renderer renderer) { + // Lazy init since it needs the renderer... + if (!_pssmPass.isInitialised()) { + _pssmPass.init(renderer); + _pssmPass.setPssmShader(terrain.getGeometryClipmapShader()); + for (int i = 0; i < _pssmPass.getNumOfSplits(); i++) { + terrain.getClipTextureState().setTexture(_pssmPass.getShadowMapTexture(i), i + 1); + } + for (int i = 0; i < ParallelSplitShadowMapPass._MAX_SPLITS; i++) { + terrain.getGeometryClipmapShader().setUniform("shadowMap" + i, i + 1); + } + } + + // Update shadowmaps + _pssmPass.updateShadowMaps(renderer); + + // Render scene and terrain with shadows + super.renderExample(renderer); + renderer.renderBuckets(); + + // Render overlay shadows for all objects except the terrain + _pssmPass.renderShadowedScene(renderer); + + // TODO: this results in text etc also being shadowed, since they are drawn in the main render... + } + + /** + * Initialize pssm pass and scene. + */ + @Override + protected void initExample() { + _canvas.setTitle("Terrain Example"); + final Camera cam = _canvas.getCanvasRenderer().getCamera(); + cam.setLocation(new Vector3(440, 215, 275)); + cam.lookAt(new Vector3(450, 140, 360), Vector3.UNIT_Y); + cam.setFrustumPerspective(70.0, (float) cam.getWidth() / cam.getHeight(), 1.0f, farPlane); + final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer(); + final RenderContext renderContext = canvasRenderer.getRenderContext(); + final Renderer renderer = canvasRenderer.getRenderer(); + GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() { + @Override + public Void call() throws Exception { + renderer.setBackgroundColor(ColorRGBA.GRAY); + return null; + } + }); + _controlHandle.setMoveSpeed(200); + + setupDefaultStates(); + + sphere.getSceneHints().setAllPickingHints(false); + sphere.getSceneHints().setCullHint(CullHint.Always); + _root.attachChild(sphere); + + try { + // Keep a separate camera to be able to freeze terrain update + terrainCamera = new Camera(cam); + + final int SIZE = 2048; + + final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.6f); + raw.setHeightRange(0.2f); + final float[] heightMap = raw.getHeightData(); + + final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 300, 1));
+ terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build(); + + terrain.setPixelShader(new UrlInputSupplier(ResourceLocatorTool
.getClassPathResource(ShadowedTerrainExample.class,
"com/ardor3d/extension/terrain/shadowedGeometryClipmapShaderPCF.frag"))); + terrain.reloadShader(); + + _root.attachChild(terrain); + } catch (final Exception e) { + logger.log(Level.SEVERE, "Problem setting up terrain...", e); + System.exit(1); + } + + // Initialize PSSM shadows + _pssmPass = new ParallelSplitShadowMapPass(directionalLight, 1024, 4);
_pssmPass.setFiltering(Filter.Pcf); + _pssmPass.setRenderShadowedScene(false); + _pssmPass.setKeepMainShader(true); + _pssmPass.setMaxShadowDistance(750); // XXX: Tune this + // _pssmPass.setMinimumLightDistance(500); // XXX: Tune this + _pssmPass.setUseSceneTexturing(false); + _pssmPass.setUseObjectCullFace(false); + // _pssmPass.setDrawDebug(true); + + final Node occluders = setupOccluders(); + _root.attachChild(occluders); + + // TODO: could we use the shadow variable in scenehints here?? + // Add objects that will get shadowed through overlay render + _pssmPass.add(occluders); + + // Add terrain in as bounds receiver as well, since it's not in the overlay list + _pssmPass.addBoundsReceiver(terrain); + + // Add our occluders that will produce shadows + ShadowCasterManager.INSTANCE.addSpatial(occluders); + + // Setup labels for presenting example info. + final Node textNodes = new Node("Text"); + _root.attachChild(textNodes); + textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho); + textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off); + + final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2; + for (int i = 0; i < _exampleInfo.length; i++) { + _exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16); + _exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0)); + textNodes.attachChild(_exampleInfo[i]); + } + + textNodes.updateGeometricState(0.0); + updateText(); + + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + updateTerrain = !updateTerrain; + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _controlHandle.setMoveSpeed(5); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _controlHandle.setMoveSpeed(50); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _controlHandle.setMoveSpeed(400); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _controlHandle.setMoveSpeed(1000); + updateText(); + } + })); + + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + groundCamera = !groundCamera; + updateText(); + } + })); + + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) { + sphere.getSceneHints().setCullHint(CullHint.Always); + } else if (sphere.getSceneHints().getCullHint() == CullHint.Always) { + sphere.getSceneHints().setCullHint(CullHint.Dynamic); + } + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug()); + terrain.reloadShader(); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + terrain.reloadShader(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2); + terrain.reloadShader(); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2); + terrain.reloadShader(); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.C), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + _pssmPass.setUpdateMainCamera(!_pssmPass.isUpdateMainCamera()); + updateText(); + } + })); + _logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() { + @Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { + final Camera cam = _canvas.getCanvasRenderer().getCamera(); + System.out.println("camera location: " + cam.getLocation()); + System.out.println("camera direction: " + cam.getDirection()); + } + })); + + } + + private Node setupOccluders() { + final Node occluders = new Node("Occluders"); + + final Box box = new Box("Box", new Vector3(), 1, 40, 1); + box.setModelBound(new BoundingBox()); + box.setRandomColors(); + + final Random rand = new Random(1337); + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + final Mesh sm = box.makeCopy(true); + + sm.setTranslation(500 + rand.nextDouble() * 300 - 150, 20 + rand.nextDouble() * 5.0, + 500 + rand.nextDouble() * 300 - 150); + occluders.attachChild(sm); + } + } + + return occluders; + } + + private void setupDefaultStates() { + _lightState.detachAll(); + directionalLight = new DirectionalLight();
directionalLight.setEnabled(true);
directionalLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
directionalLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
directionalLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
directionalLight.setDirection(lightPosition.normalize(null).negateLocal());
_lightState.attach(directionalLight);
_lightState.setEnabled(true); + + final CullState cs = new CullState(); + cs.setEnabled(true); + cs.setCullFace(CullState.Face.Back); + _root.setRenderState(cs); + + final FogState fs = new FogState(); + fs.setStart(farPlane / 2.0f); + fs.setEnd(farPlane); + fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); + fs.setDensityFunction(DensityFunction.Linear); + _root.setRenderState(fs); + } + + /** + * Update text information. + */ + private void updateText() { + _exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h"); + _exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic)); + _exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly")); + _exampleInfo[3].setText("[J] Regenerate heightmap/texture"); + _exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain); + } +} diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ShapesPlusProceduralTerrainExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ShapesPlusProceduralTerrainExample.java index ac2a1c1..e6b9b3d 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ShapesPlusProceduralTerrainExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ShapesPlusProceduralTerrainExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.io.IOException;
import java.util.concurrent.Callable;
import javax.imageio.ImageIO;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.client.TextureClipmap;
import com.ardor3d.extension.terrain.providers.awt.AbstractAwtElement;
import com.ardor3d.extension.terrain.providers.awt.AwtImageElement;
import com.ardor3d.extension.terrain.providers.awt.AwtShapeElement;
import com.ardor3d.extension.terrain.providers.awt.AwtTextureSource;
import com.ardor3d.extension.terrain.providers.procedural.ProceduralTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.TextureStoreFormat;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.MathUtils;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Transform;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.functions.FbmFunction3D;
import com.ardor3d.math.functions.Function3D;
import com.ardor3d.math.functions.Functions;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.resource.ResourceLocatorTool;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures'. We merge AWT drawing with the terrain
* texture in real time. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ShapesPlusProceduralTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ShapesPlusProceduralTerrainExample.jpg", //
maxHeapMemory = 128)
public class ShapesPlusProceduralTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private final float heightScale = 200;
private Terrain terrain;
private boolean groundCamera = false;
private Camera terrainCamera;
Transform ovalTrans = new Transform();
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
public static void main(final String[] args) {
ExampleBase.start(ShapesPlusProceduralTerrainExample.class);
}
private double counter = 0;
private int frames = 0;
private final double awtUpdate = 1.0 / 15.0; // 15 fps
private double awtCounter = 0;
@Override
protected void updateExample(final ReadOnlyTimer timer) {
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = frames / counter;
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
final Camera camera = _canvas.getCanvasRenderer().getCamera();
awtCounter += timer.getTimePerFrame();
if (awtCounter > awtUpdate) {
final double tis = timer.getTimeInSeconds() * 0.75;
ovalTrans.setTranslation(250 * MathUtils.sin(-tis), 150 * MathUtils.cos(tis), 0);
oval.setTransform(ovalTrans);
awtCounter -= awtUpdate;
}
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
}
private AwtTextureSource awtTextureSource;
private AwtShapeElement rectangle;
private AwtShapeElement oval;
private AwtImageElement bubble;
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
for (int i = 0; i < 9; i++) {
final double x = (i % 3 - 1) * 128.0;
final double z = (i / 3 - 1) * 128.0;
final Box b = new Box("" + i, new Vector3(x, 0, z), 5, 150, 5);
_root.attachChild(b);
}
// Setup main camera.
_canvas.setTitle("Shapes + Procedural Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(50);
setupDefaultStates();
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
awtTextureSource = new AwtTextureSource(8, TextureStoreFormat.RGBA8); // Same as procedural one
final double scale = 1.0 / 4000.0;
Function3D functionTmp = new FbmFunction3D(Functions.simplexNoise(), 9, 0.5, 0.5, 3.14);
functionTmp = Functions.clamp(functionTmp, -1.2, 1.2);
final Function3D function = Functions.scaleInput(functionTmp, scale, scale, 1);
final TerrainDataProvider baseTerrainDataProvider = new ProceduralTerrainDataProvider(function,
new Vector3(1, heightScale, 1), -1.2f, 1.2f);
final TerrainBuilder terrainBuilder = new TerrainBuilder(baseTerrainDataProvider, terrainCamera);
terrainBuilder.addTextureConnection(awtTextureSource);
terrain = terrainBuilder.setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
// add some shapes
rectangle = new AwtShapeElement(new Rectangle(400, 50));
Transform t = new Transform();
t.setRotation(new Matrix3().fromAngles(0, 0, 45 * MathUtils.DEG_TO_RAD));
rectangle.setTransform(t);
awtTextureSource.getProvider().addElement(rectangle);
oval = new AwtShapeElement(new Ellipse2D.Float(0, 0, 250, 150));
oval.setFillColor(Color.red);
// set transparency
oval.setCompositeOverride(AbstractAwtElement.makeAlphaComposite(.75f));
awtTextureSource.getProvider().addElement(oval);
// add an image element to test.
t = new Transform();
t.setScale(2.0);
t.translate(-250, 150, 0);
addBubble(t);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(200);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
for (final TextureClipmap clipmap : terrain.getTextureClipmaps()) {
clipmap.setScale(terrain.getTextureClipmap().getScale() / 2);
}
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
for (final TextureClipmap clipmap : terrain.getTextureClipmaps()) {
clipmap.setScale(terrain.getTextureClipmap().getScale() * 2);
}
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(-5000, 500, -5000);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(5000, 500, 5000);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Transform t = new Transform();
t.setScale(MathUtils.nextRandomDouble() * 4.9 + 0.1);
t.translate(MathUtils.nextRandomDouble() * 500 - 250, MathUtils.nextRandomDouble() * 500 - 250, 0);
addBubble(t);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
protected void addBubble(final Transform t) {
java.awt.Image bubbleImg = null;
try {
bubbleImg = ImageIO.read(ResourceLocatorTool.getClassPathResourceAsStream(
ShapesPlusProceduralTerrainExample.class, "com/ardor3d/example/media/images/ball.png"));
} catch (final IOException e) {
e.printStackTrace();
System.exit(-1);
}
bubble = new AwtImageElement(bubbleImg);
bubble.setTransform(t);
awtTextureSource.getProvider().addElement(bubble);
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[R] Draw texture debug: " + terrain.getTextureClipmap().isShowDebug());
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.io.IOException;
import java.util.concurrent.Callable;
import javax.imageio.ImageIO;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.client.TextureClipmap;
import com.ardor3d.extension.terrain.providers.awt.AbstractAwtElement;
import com.ardor3d.extension.terrain.providers.awt.AwtImageElement;
import com.ardor3d.extension.terrain.providers.awt.AwtShapeElement;
import com.ardor3d.extension.terrain.providers.awt.AwtTextureSource;
import com.ardor3d.extension.terrain.providers.procedural.ProceduralTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.TextureStoreFormat;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.MathUtils;
import com.ardor3d.math.Matrix3;
import com.ardor3d.math.Transform;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.functions.FbmFunction3D;
import com.ardor3d.math.functions.Function3D;
import com.ardor3d.math.functions.Functions;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Box;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.resource.ResourceLocatorTool;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures'. We merge AWT drawing with the terrain
* texture in real time. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ShapesPlusProceduralTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ShapesPlusProceduralTerrainExample.jpg", //
maxHeapMemory = 128)
public class ShapesPlusProceduralTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 8000.0f;
private final float heightScale = 200;
private Terrain terrain;
private boolean groundCamera = false;
private Camera terrainCamera;
Transform ovalTrans = new Transform();
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
public static void main(final String[] args) {
ExampleBase.start(ShapesPlusProceduralTerrainExample.class);
}
private double counter = 0;
private int frames = 0;
private final double awtUpdate = 1.0 / 15.0; // 15 fps
private double awtCounter = 0;
@Override
protected void updateExample(final ReadOnlyTimer timer) {
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = frames / counter;
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
final Camera camera = _canvas.getCanvasRenderer().getCamera();
awtCounter += timer.getTimePerFrame();
if (awtCounter > awtUpdate) {
final double tis = timer.getTimeInSeconds() * 0.75;
ovalTrans.setTranslation(250 * MathUtils.sin(-tis), 150 * MathUtils.cos(tis), 0);
oval.setTransform(ovalTrans);
awtCounter -= awtUpdate;
}
// Make sure camera is above terrain
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ());
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getY() < height + 3)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height + 3, camera.getLocation().getZ()));
}
if (updateTerrain) {
terrainCamera.set(camera);
}
}
private AwtTextureSource awtTextureSource;
private AwtShapeElement rectangle;
private AwtShapeElement oval;
private AwtImageElement bubble;
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
for (int i = 0; i < 9; i++) {
final double x = (i % 3 - 1) * 128.0;
final double z = (i / 3 - 1) * 128.0;
final Box b = new Box("" + i, new Vector3(x, 0, z), 5, 150, 5);
_root.attachChild(b);
}
// Setup main camera.
_canvas.setTitle("Shapes + Procedural Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 300, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, 300, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setMoveSpeed(50);
setupDefaultStates();
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
awtTextureSource = new AwtTextureSource(8, TextureStoreFormat.RGBA8); // Same as procedural one
final double scale = 1.0 / 4000.0;
Function3D functionTmp = new FbmFunction3D(Functions.simplexNoise(), 9, 0.5, 0.5, 3.14);
functionTmp = Functions.clamp(functionTmp, -1.2, 1.2);
final Function3D function = Functions.scaleInput(functionTmp, scale, scale, 1);
final TerrainDataProvider baseTerrainDataProvider = new ProceduralTerrainDataProvider(function,
new Vector3(1, heightScale, 1), -1.2f, 1.2f);
final TerrainBuilder terrainBuilder = new TerrainBuilder(baseTerrainDataProvider, terrainCamera);
terrainBuilder.addTextureConnection(awtTextureSource);
terrain = terrainBuilder.setShowDebugPanels(true).build();
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
// add some shapes
rectangle = new AwtShapeElement(new Rectangle(400, 50));
Transform t = new Transform();
t.setRotation(new Matrix3().fromAngles(0, 0, 45 * MathUtils.DEG_TO_RAD));
rectangle.setTransform(t);
awtTextureSource.getProvider().addElement(rectangle);
oval = new AwtShapeElement(new Ellipse2D.Float(0, 0, 250, 150));
oval.setFillColor(Color.red);
// set transparency
oval.setCompositeOverride(AbstractAwtElement.makeAlphaComposite(.75f));
awtTextureSource.getProvider().addElement(oval);
// add an image element to test.
t = new Transform();
t.setScale(2.0);
t.translate(-250, 150, 0);
addBubble(t);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(200);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
for (final TextureClipmap clipmap : terrain.getTextureClipmaps()) {
clipmap.setScale(terrain.getTextureClipmap().getScale() / 2);
}
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
for (final TextureClipmap clipmap : terrain.getTextureClipmaps()) {
clipmap.setScale(terrain.getTextureClipmap().getScale() * 2);
}
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(-5000, 500, -5000);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(5000, 500, 5000);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 1500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Transform t = new Transform();
t.setScale(MathUtils.nextRandomDouble() * 4.9 + 0.1);
t.translate(MathUtils.nextRandomDouble() * 500 - 250, MathUtils.nextRandomDouble() * 500 - 250, 0);
addBubble(t);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 1500.0);
}
}));
}
protected void addBubble(final Transform t) {
java.awt.Image bubbleImg = null;
try {
bubbleImg = ImageIO.read(ResourceLocatorTool.getClassPathResourceAsStream(
ShapesPlusProceduralTerrainExample.class, "com/ardor3d/example/media/images/ball.png"));
} catch (final IOException e) {
e.printStackTrace();
System.exit(-1);
}
bubble = new AwtImageElement(bubbleImg);
bubble.setTransform(t);
awtTextureSource.getProvider().addElement(bubble);
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[R] Draw texture debug: " + terrain.getTextureClipmap().isShowDebug());
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/TerrainWaterExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/TerrainWaterExample.java index 2958130..b17b63f 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/TerrainWaterExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/TerrainWaterExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.nio.FloatBuffer;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.effect.water.WaterNode;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.providers.procedural.ProceduralTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Plane;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.functions.FbmFunction3D;
import com.ardor3d.math.functions.Function3D;
import com.ardor3d.math.functions.Functions;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing how to combine the terrain and water systems. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.TerrainWaterExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_TerrainWaterExample.jpg", //
maxHeapMemory = 128)
public class TerrainWaterExample extends ExampleBase {
private final int SIZE = 2048;
private Terrain terrain;
private boolean updateTerrain = true;
private final float farPlane = 3500.0f;
private final float heightOffset = 3.0f;
/** The water instance taking care of the water rendering. */
private WaterNode waterNode;
private boolean aboveWater = true;
/** Node containing debug quads for showing waternode render textures. */
private Node debugQuadsNode;
/** The quad used as geometry for the water. */
private Quad waterQuad;
private boolean groundCamera = false;
private Camera terrainCamera;
private Skybox skybox;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final double textureScale = 0.05;
private FogState fogState;
private boolean showUI = true;
private final Ray3 pickRay = new Ray3();
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[8];
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(final String[] args) {
start(TerrainWaterExample.class);
}
private double counter = 0;
private int frames = 0;
/**
* Update the PassManager, skybox, camera position, etc.
*
* @param timer
* the application timer
*/
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ())
+ heightOffset;
if (groundCamera || camera.getLocation().getY() < height) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height, camera.getLocation().getZ()));
}
if (aboveWater && camera.getLocation().getY() < waterNode.getWaterHeight()) {
fogState.setStart(-1000f);
fogState.setEnd(farPlane / 10f);
fogState.setColor(new ColorRGBA(0.0f, 0.0f, 0.1f, 1.0f));
aboveWater = false;
} else if (!aboveWater && camera.getLocation().getY() >= waterNode.getWaterHeight()) {
fogState.setStart(farPlane / 2.0f);
fogState.setEnd(farPlane);
fogState.setColor(new ColorRGBA(0.96f, 0.97f, 1.0f, 1.0f));
aboveWater = true;
}
if (updateTerrain) {
terrainCamera.set(camera);
}
skybox.setTranslation(camera.getLocation());
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = (frames / counter);
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
final Vector3 transVec = new Vector3(camera.getLocation().getX(), waterNode.getWaterHeight(), camera
.getLocation().getZ());
setTextureCoords(0, transVec.getX(), -transVec.getZ(), textureScale);
// vertex coords
setVertexCoords(transVec.getX(), transVec.getY(), transVec.getZ());
waterNode.update(timer.getTimePerFrame());
}
/**
* Render example.
*
* @param renderer
* the renderer
*/
@Override
protected void renderExample(final Renderer renderer) {
super.renderExample(renderer);
if (debugQuadsNode == null) {
createDebugQuads();
_root.attachChild(debugQuadsNode);
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain + Water - Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 100, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 100, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer().getCamera().setFrustumPerspective(
65.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
_controlHandle.setMoveSpeed(50);
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
fogState = new FogState();
fogState.setStart(farPlane / 2.0f);
fogState.setEnd(farPlane);
fogState.setColor(new ColorRGBA(0.96f, 0.97f, 1.0f, 1.0f));
fogState.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fogState);
// add our sphere, but have it off for now.
sphere.getSceneHints().setCullHint(CullHint.Always);
sphere.getSceneHints().setAllPickingHints(false);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
final double scale = 1.0 / 4000.0;
Function3D functionTmp = new FbmFunction3D(Functions.simplexNoise(), 9, 0.5, 0.5, 3.14);
functionTmp = Functions.clamp(functionTmp, -1.2, 1.2);
final Function3D function = Functions.scaleInput(functionTmp, scale, scale, 1);
final TerrainDataProvider terrainDataProvider = new ProceduralTerrainDataProvider(function, new Vector3(1,
200, 1), -1.2f, 1.2f);
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
} catch (final Exception ex1) {
ex1.printStackTrace();
}
final Node reflectedNode = new Node("reflectNode");
reflectedNode.attachChild(terrain);
skybox = buildSkyBox();
skybox.getSceneHints().setAllPickingHints(false);
reflectedNode.attachChild(skybox);
final Camera cam = _canvas.getCanvasRenderer().getCamera();
// Create a new WaterNode with refraction enabled.
waterNode = new WaterNode(cam, 2, false, true);
// Setup textures to use for the water.
waterNode.setNormalMapTextureString("images/water/normalmap3.dds");
waterNode.setDudvMapTextureString("images/water/dudvmap.png");
waterNode.setFallbackMapTextureString("images/water/water2.png");
waterNode.useFadeToFogColor(true);
waterNode.setSpeedReflection(0.02);
waterNode.setSpeedReflection(-0.01);
// setting to default value just to show
waterNode.setWaterPlane(new Plane(new Vector3(0.0, 1.0, 0.0), 40.0));
// Create a quad to use as geometry for the water.
waterQuad = new Quad("waterQuad", 1, 1);
// Hack the quad normals to point up in the y-axis. Since we are manipulating the vertices as
// we move this is more convenient than rotating the quad.
final FloatBuffer normBuf = waterQuad.getMeshData().getNormalBuffer();
normBuf.clear();
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
waterNode.attachChild(waterQuad);
waterNode.addReflectedScene(reflectedNode);
waterNode.setSkybox(skybox);
_root.attachChild(reflectedNode);
_root.attachChild(waterNode);
// Setup cam above water and terrain
final Camera camera = _canvas.getCanvasRenderer().getCamera();
final double height = Math.max(terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ()),
waterNode.getWaterHeight())
+ heightOffset;
if (camera.getLocation().getY() < height) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height, camera.getLocation().getZ()));
}
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() - 20;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
sphere.getSceneHints().setCullHint(
sphere.getSceneHints().getCullHint() == CullHint.Always ? CullHint.Dynamic : CullHint.Always);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
showUI = !showUI;
if (showUI) {
textNodes.getSceneHints().setCullHint(CullHint.Never);
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
} else {
textNodes.getSceneHints().setCullHint(CullHint.Always);
debugQuadsNode.getSceneHints().setCullHint(CullHint.Always);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.B), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
waterNode.setDoBlurReflection(!waterNode.isDoBlurReflection());
waterNode.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(new Vector3(camera.getLocation().getX() + 5000, camera.getLocation().getY(), camera
.getLocation().getZ()));
updateText();
}
}));
}
/**
* Sets the vertex coords of the quad.
*
* @param x
* the x
* @param y
* the y
* @param z
* the z
*/
private void setVertexCoords(final double x, final double y, final double z) {
final FloatBuffer vertBuf = waterQuad.getMeshData().getVertexBuffer();
vertBuf.clear();
vertBuf.put((float) (x - farPlane)).put((float) y).put((float) (z - farPlane));
vertBuf.put((float) (x - farPlane)).put((float) y).put((float) (z + farPlane));
vertBuf.put((float) (x + farPlane)).put((float) y).put((float) (z + farPlane));
vertBuf.put((float) (x + farPlane)).put((float) y).put((float) (z - farPlane));
}
/**
* Sets the texture coords of the quad.
*
* @param buffer
* the buffer
* @param x
* the x
* @param y
* the y
* @param textureScale
* the texture scale
*/
private void setTextureCoords(final int buffer, double x, double y, double textureScale) {
x *= textureScale * 0.5f;
y *= textureScale * 0.5f;
textureScale = farPlane * textureScale;
FloatBuffer texBuf;
texBuf = waterQuad.getMeshData().getTextureBuffer(buffer);
texBuf.clear();
texBuf.put((float) x).put((float) (textureScale + y));
texBuf.put((float) x).put((float) y);
texBuf.put((float) (textureScale + x)).put((float) y);
texBuf.put((float) (textureScale + x)).put((float) (textureScale + y));
}
/**
* Builds the sky box.
*/
private Skybox buildSkyBox() {
final Skybox skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
return skybox;
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("Heightmap size: " + SIZE + "x" + SIZE);
_exampleInfo[1].setText("Spec: One meter per heightmap value");
_exampleInfo[2].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() + " m/s");
_exampleInfo[3].setText("[U] Update terrain: " + updateTerrain);
_exampleInfo[4].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[5].setText("[P] Toggle showing a sphere that follows the ground using picking: "
+ (sphere.getSceneHints().getCullHint() != CullHint.Always));
_exampleInfo[6].setText("[B] Blur reflection: " + waterNode.isDoBlurReflection());
_exampleInfo[7].setText("[V] Show/Hide UI");
}
/**
* Creates the debug quads.
*/
private void createDebugQuads() {
debugQuadsNode = new Node("quadNode");
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
final double quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
Quad debugQuad = new Quad("reflectionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
TextureState ts = new TextureState();
ts.setTexture(waterNode.getTextureReflect());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 1.0, 1.0);
debugQuadsNode.attachChild(debugQuad);
if (waterNode.getTextureRefract() != null) {
debugQuad = new Quad("refractionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
ts = new TextureState();
ts.setTexture(waterNode.getTextureRefract());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 2.1, 1.0);
debugQuadsNode.attachChild(debugQuad);
}
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.nio.FloatBuffer;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.effect.water.WaterNode;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.providers.procedural.ProceduralTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Plane;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.functions.FbmFunction3D;
import com.ardor3d.math.functions.Function3D;
import com.ardor3d.math.functions.Functions;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Quad;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing how to combine the terrain and water systems. Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.TerrainWaterExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_TerrainWaterExample.jpg", //
maxHeapMemory = 128)
public class TerrainWaterExample extends ExampleBase {
private final int SIZE = 2048;
private Terrain terrain;
private boolean updateTerrain = true;
private final float farPlane = 3500.0f;
private final float heightOffset = 3.0f;
/** The water instance taking care of the water rendering. */
private WaterNode waterNode;
private boolean aboveWater = true;
/** Node containing debug quads for showing waternode render textures. */
private Node debugQuadsNode;
/** The quad used as geometry for the water. */
private Quad waterQuad;
private boolean groundCamera = false;
private Camera terrainCamera;
private Skybox skybox;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final double textureScale = 0.05;
private FogState fogState;
private boolean showUI = true;
private final Ray3 pickRay = new Ray3();
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[8];
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(final String[] args) {
start(TerrainWaterExample.class);
}
private double counter = 0;
private int frames = 0;
/**
* Update the PassManager, skybox, camera position, etc.
*
* @param timer
* the application timer
*/
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
final double height = terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ())
+ heightOffset;
if (groundCamera || camera.getLocation().getY() < height) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height, camera.getLocation().getZ()));
}
if (aboveWater && camera.getLocation().getY() < waterNode.getWaterHeight()) {
fogState.setStart(-1000f);
fogState.setEnd(farPlane / 10f);
fogState.setColor(new ColorRGBA(0.0f, 0.0f, 0.1f, 1.0f));
aboveWater = false;
} else if (!aboveWater && camera.getLocation().getY() >= waterNode.getWaterHeight()) {
fogState.setStart(farPlane / 2.0f);
fogState.setEnd(farPlane);
fogState.setColor(new ColorRGBA(0.96f, 0.97f, 1.0f, 1.0f));
aboveWater = true;
}
if (updateTerrain) {
terrainCamera.set(camera);
}
skybox.setTranslation(camera.getLocation());
counter += timer.getTimePerFrame();
frames++;
if (counter > 1) {
final double fps = (frames / counter);
counter = 0;
frames = 0;
System.out.printf("%7.1f FPS\n", fps);
}
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
final Vector3 transVec = new Vector3(camera.getLocation().getX(), waterNode.getWaterHeight(), camera
.getLocation().getZ());
setTextureCoords(0, transVec.getX(), -transVec.getZ(), textureScale);
// vertex coords
setVertexCoords(transVec.getX(), transVec.getY(), transVec.getZ());
waterNode.update(timer.getTimePerFrame());
}
/**
* Render example.
*
* @param renderer
* the renderer
*/
@Override
protected void renderExample(final Renderer renderer) {
super.renderExample(renderer);
if (debugQuadsNode == null) {
createDebugQuads();
_root.attachChild(debugQuadsNode);
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Terrain + Water - Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 100, 0));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(0, 100, 1), Vector3.UNIT_Y);
_canvas.getCanvasRenderer().getCamera().setFrustumPerspective(
65.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
_controlHandle.setMoveSpeed(50);
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
fogState = new FogState();
fogState.setStart(farPlane / 2.0f);
fogState.setEnd(farPlane);
fogState.setColor(new ColorRGBA(0.96f, 0.97f, 1.0f, 1.0f));
fogState.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fogState);
// add our sphere, but have it off for now.
sphere.getSceneHints().setCullHint(CullHint.Always);
sphere.getSceneHints().setAllPickingHints(false);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
final double scale = 1.0 / 4000.0;
Function3D functionTmp = new FbmFunction3D(Functions.simplexNoise(), 9, 0.5, 0.5, 3.14);
functionTmp = Functions.clamp(functionTmp, -1.2, 1.2);
final Function3D function = Functions.scaleInput(functionTmp, scale, scale, 1);
final TerrainDataProvider terrainDataProvider = new ProceduralTerrainDataProvider(function, new Vector3(1,
200, 1), -1.2f, 1.2f);
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
} catch (final Exception ex1) {
ex1.printStackTrace();
}
final Node reflectedNode = new Node("reflectNode");
reflectedNode.attachChild(terrain);
skybox = buildSkyBox();
skybox.getSceneHints().setAllPickingHints(false);
reflectedNode.attachChild(skybox);
final Camera cam = _canvas.getCanvasRenderer().getCamera();
// Create a new WaterNode with refraction enabled.
waterNode = new WaterNode(cam, 2, false, true);
// Setup textures to use for the water.
waterNode.setNormalMapTextureString("images/water/normalmap3.dds");
waterNode.setDudvMapTextureString("images/water/dudvmap.png");
waterNode.setFallbackMapTextureString("images/water/water2.png");
waterNode.useFadeToFogColor(true);
waterNode.setSpeedReflection(0.02);
waterNode.setSpeedReflection(-0.01);
// setting to default value just to show
waterNode.setWaterPlane(new Plane(new Vector3(0.0, 1.0, 0.0), 40.0));
// Create a quad to use as geometry for the water.
waterQuad = new Quad("waterQuad", 1, 1);
// Hack the quad normals to point up in the y-axis. Since we are manipulating the vertices as
// we move this is more convenient than rotating the quad.
final FloatBuffer normBuf = waterQuad.getMeshData().getNormalBuffer();
normBuf.clear();
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
waterNode.attachChild(waterQuad);
waterNode.addReflectedScene(reflectedNode);
waterNode.setSkybox(skybox);
_root.attachChild(reflectedNode);
_root.attachChild(waterNode);
// Setup cam above water and terrain
final Camera camera = _canvas.getCanvasRenderer().getCamera();
final double height = Math.max(terrain.getHeightAt(camera.getLocation().getX(), camera.getLocation().getZ()),
waterNode.getWaterHeight())
+ heightOffset;
if (camera.getLocation().getY() < height) {
camera.setLocation(new Vector3(camera.getLocation().getX(), height, camera.getLocation().getZ()));
}
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() - 20;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
sphere.getSceneHints().setCullHint(
sphere.getSceneHints().getCullHint() == CullHint.Always ? CullHint.Dynamic : CullHint.Always);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.V), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
showUI = !showUI;
if (showUI) {
textNodes.getSceneHints().setCullHint(CullHint.Never);
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
} else {
textNodes.getSceneHints().setCullHint(CullHint.Always);
debugQuadsNode.getSceneHints().setCullHint(CullHint.Always);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.B), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
waterNode.setDoBlurReflection(!waterNode.isDoBlurReflection());
waterNode.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(new Vector3(camera.getLocation().getX() + 5000, camera.getLocation().getY(), camera
.getLocation().getZ()));
updateText();
}
}));
}
/**
* Sets the vertex coords of the quad.
*
* @param x
* the x
* @param y
* the y
* @param z
* the z
*/
private void setVertexCoords(final double x, final double y, final double z) {
final FloatBuffer vertBuf = waterQuad.getMeshData().getVertexBuffer();
vertBuf.clear();
vertBuf.put((float) (x - farPlane)).put((float) y).put((float) (z - farPlane));
vertBuf.put((float) (x - farPlane)).put((float) y).put((float) (z + farPlane));
vertBuf.put((float) (x + farPlane)).put((float) y).put((float) (z + farPlane));
vertBuf.put((float) (x + farPlane)).put((float) y).put((float) (z - farPlane));
}
/**
* Sets the texture coords of the quad.
*
* @param buffer
* the buffer
* @param x
* the x
* @param y
* the y
* @param textureScale
* the texture scale
*/
private void setTextureCoords(final int buffer, double x, double y, double textureScale) {
x *= textureScale * 0.5f;
y *= textureScale * 0.5f;
textureScale = farPlane * textureScale;
FloatBuffer texBuf;
texBuf = waterQuad.getMeshData().getTextureBuffer(buffer);
texBuf.clear();
texBuf.put((float) x).put((float) (textureScale + y));
texBuf.put((float) x).put((float) y);
texBuf.put((float) (textureScale + x)).put((float) y);
texBuf.put((float) (textureScale + x)).put((float) (textureScale + y));
}
/**
* Builds the sky box.
*/
private Skybox buildSkyBox() {
final Skybox skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
return skybox;
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("Heightmap size: " + SIZE + "x" + SIZE);
_exampleInfo[1].setText("Spec: One meter per heightmap value");
_exampleInfo[2].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() + " m/s");
_exampleInfo[3].setText("[U] Update terrain: " + updateTerrain);
_exampleInfo[4].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[5].setText("[P] Toggle showing a sphere that follows the ground using picking: "
+ (sphere.getSceneHints().getCullHint() != CullHint.Always));
_exampleInfo[6].setText("[B] Blur reflection: " + waterNode.isDoBlurReflection());
_exampleInfo[7].setText("[V] Show/Hide UI");
}
/**
* Creates the debug quads.
*/
private void createDebugQuads() {
debugQuadsNode = new Node("quadNode");
debugQuadsNode.getSceneHints().setCullHint(CullHint.Never);
final double quadSize = _canvas.getCanvasRenderer().getCamera().getWidth() / 10;
Quad debugQuad = new Quad("reflectionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
TextureState ts = new TextureState();
ts.setTexture(waterNode.getTextureReflect());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 1.0, 1.0);
debugQuadsNode.attachChild(debugQuad);
if (waterNode.getTextureRefract() != null) {
debugQuad = new Quad("refractionQuad", quadSize, quadSize);
debugQuad.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
debugQuad.getSceneHints().setCullHint(CullHint.Never);
debugQuad.getSceneHints().setLightCombineMode(LightCombineMode.Off);
ts = new TextureState();
ts.setTexture(waterNode.getTextureRefract());
debugQuad.setRenderState(ts);
debugQuad.setTranslation(quadSize * 0.6, quadSize * 2.1, 1.0);
debugQuadsNode.attachChild(debugQuad);
}
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ZupTerrainExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ZupTerrainExample.java index 29ff14a..b9369d3 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ZupTerrainExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/terrain/ZupTerrainExample.java @@ -1 +1 @@ -/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.heightmap.MidPointHeightMapGenerator;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.MathUtils;
import com.ardor3d.math.Quaternion;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' using Z-Up. This is done by flipping the
* terrain system from y-up to z-up and inverting interactions with it back to the y-up terrain coordinate space.
* Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ZupTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ZupTerrainExample.jpg", //
maxHeapMemory = 128)
public class ZupTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 10000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
private Skybox skybox;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
public static void main(final String[] args) {
ExampleBase.start(ZupTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(Vector3.NEG_UNIT_Z);
final PrimitivePickResults pickResultsCam = new PrimitivePickResults();
pickResultsCam.setCheckDistance(true);
PickingUtil.findPick(terrain, pickRay, pickResultsCam);
if (pickResultsCam.getNumber() != 0) {
final Vector3 intersectionPoint = pickResultsCam.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
final double height = intersectionPoint.getZ();
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getZ() < height + 5)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), camera.getLocation().getY(), height + 5));
}
}
if (updateTerrain) {
terrainCamera.set(camera);
}
skybox.setTranslation(camera.getLocation());
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Z-up Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 0, 300));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, -1, 300), Vector3.UNIT_Z);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setUpAxis(Vector3.UNIT_Z);
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
final int SIZE = 2048;
final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.5f);
raw.setHeightRange(0.2f);
final float[] heightMap = raw.getHeightData();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 300, 1));
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
terrain.setRotation(new Quaternion().fromAngleAxis(MathUtils.HALF_PI, Vector3.UNIT_X));
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
skybox = buildSkyBox();
skybox.getSceneHints().setAllPickingHints(false);
_root.attachChild(skybox);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() + 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() - 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Builds the sky box.
*/
private Skybox buildSkyBox() {
final Skybox skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
skybox.setRotation(new Quaternion().fromAngleAxis(MathUtils.HALF_PI, Vector3.UNIT_X));
return skybox;
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file +/**
* Copyright (c) 2008-2014 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/
package com.ardor3d.example.terrain;
import java.util.concurrent.Callable;
import com.ardor3d.example.ExampleBase;
import com.ardor3d.example.Purpose;
import com.ardor3d.extension.terrain.client.Terrain;
import com.ardor3d.extension.terrain.client.TerrainBuilder;
import com.ardor3d.extension.terrain.client.TerrainDataProvider;
import com.ardor3d.extension.terrain.heightmap.MidPointHeightMapGenerator;
import com.ardor3d.extension.terrain.providers.array.ArrayTerrainDataProvider;
import com.ardor3d.framework.Canvas;
import com.ardor3d.framework.CanvasRenderer;
import com.ardor3d.image.Texture;
import com.ardor3d.input.Key;
import com.ardor3d.input.logical.InputTrigger;
import com.ardor3d.input.logical.KeyPressedCondition;
import com.ardor3d.input.logical.TriggerAction;
import com.ardor3d.input.logical.TwoInputStates;
import com.ardor3d.intersection.PickingUtil;
import com.ardor3d.intersection.PrimitivePickResults;
import com.ardor3d.light.DirectionalLight;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.MathUtils;
import com.ardor3d.math.Quaternion;
import com.ardor3d.math.Ray3;
import com.ardor3d.math.Vector3;
import com.ardor3d.renderer.Camera;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.queue.RenderBucketType;
import com.ardor3d.renderer.state.CullState;
import com.ardor3d.renderer.state.FogState;
import com.ardor3d.renderer.state.FogState.DensityFunction;
import com.ardor3d.scenegraph.Node;
import com.ardor3d.scenegraph.extension.Skybox;
import com.ardor3d.scenegraph.hint.CullHint;
import com.ardor3d.scenegraph.hint.LightCombineMode;
import com.ardor3d.scenegraph.shape.Sphere;
import com.ardor3d.ui.text.BasicText;
import com.ardor3d.util.GameTaskQueue;
import com.ardor3d.util.GameTaskQueueManager;
import com.ardor3d.util.ReadOnlyTimer;
import com.ardor3d.util.TextureManager;
/**
* Example showing the Geometry Clipmap Terrain system with 'MegaTextures' using Z-Up. This is done by flipping the
* terrain system from y-up to z-up and inverting interactions with it back to the y-up terrain coordinate space.
* Requires GLSL support.
*/
@Purpose(htmlDescriptionKey = "com.ardor3d.example.terrain.ZupTerrainExample", //
thumbnailPath = "com/ardor3d/example/media/thumbnails/terrain_ZupTerrainExample.jpg", //
maxHeapMemory = 128)
public class ZupTerrainExample extends ExampleBase {
private boolean updateTerrain = true;
private final float farPlane = 10000.0f;
private Terrain terrain;
private final Sphere sphere = new Sphere("sp", 16, 16, 1);
private final Ray3 pickRay = new Ray3();
private boolean groundCamera = false;
private Camera terrainCamera;
private Skybox skybox;
/** Text fields used to present info about the example. */
private final BasicText _exampleInfo[] = new BasicText[5];
public static void main(final String[] args) {
ExampleBase.start(ZupTerrainExample.class);
}
@Override
protected void updateExample(final ReadOnlyTimer timer) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
// Make sure camera is above terrain
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(Vector3.NEG_UNIT_Z);
final PrimitivePickResults pickResultsCam = new PrimitivePickResults();
pickResultsCam.setCheckDistance(true);
PickingUtil.findPick(terrain, pickRay, pickResultsCam);
if (pickResultsCam.getNumber() != 0) {
final Vector3 intersectionPoint = pickResultsCam.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
final double height = intersectionPoint.getZ();
if (height > -Float.MAX_VALUE && (groundCamera || camera.getLocation().getZ() < height + 5)) {
camera.setLocation(new Vector3(camera.getLocation().getX(), camera.getLocation().getY(), height + 5));
}
}
if (updateTerrain) {
terrainCamera.set(camera);
}
skybox.setTranslation(camera.getLocation());
// if we're picking...
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
// Set up our pick ray
pickRay.setOrigin(camera.getLocation());
pickRay.setDirection(camera.getDirection());
// do pick and move the sphere
final PrimitivePickResults pickResults = new PrimitivePickResults();
pickResults.setCheckDistance(true);
PickingUtil.findPick(_root, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
final Vector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord()
.getIntersectionPoint(0);
sphere.setTranslation(intersectionPoint);
// XXX: maybe change the color of the ball for valid vs. invalid?
}
}
}
/**
* Initialize pssm pass and scene.
*/
@Override
protected void initExample() {
// Setup main camera.
_canvas.setTitle("Z-up Terrain Example");
_canvas.getCanvasRenderer().getCamera().setLocation(new Vector3(0, 0, 300));
_canvas.getCanvasRenderer().getCamera().lookAt(new Vector3(1, -1, 300), Vector3.UNIT_Z);
_canvas.getCanvasRenderer()
.getCamera()
.setFrustumPerspective(
70.0,
(float) _canvas.getCanvasRenderer().getCamera().getWidth()
/ _canvas.getCanvasRenderer().getCamera().getHeight(), 1.0f, farPlane);
final CanvasRenderer canvasRenderer = _canvas.getCanvasRenderer();
final RenderContext renderContext = canvasRenderer.getRenderContext();
final Renderer renderer = canvasRenderer.getRenderer();
GameTaskQueueManager.getManager(renderContext).getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Void>() {
@Override
public Void call() throws Exception {
renderer.setBackgroundColor(ColorRGBA.GRAY);
return null;
}
});
_controlHandle.setUpAxis(Vector3.UNIT_Z);
_controlHandle.setMoveSpeed(200);
setupDefaultStates();
sphere.getSceneHints().setAllPickingHints(false);
sphere.getSceneHints().setCullHint(CullHint.Always);
_root.attachChild(sphere);
try {
// Keep a separate camera to be able to freeze terrain update
final Camera camera = _canvas.getCanvasRenderer().getCamera();
terrainCamera = new Camera(camera);
final int SIZE = 2048;
final MidPointHeightMapGenerator raw = new MidPointHeightMapGenerator(SIZE, 0.5f);
raw.setHeightRange(0.2f);
final float[] heightMap = raw.getHeightData();
final TerrainDataProvider terrainDataProvider = new ArrayTerrainDataProvider(heightMap, SIZE, new Vector3(
1, 300, 1));
terrain = new TerrainBuilder(terrainDataProvider, terrainCamera).setShowDebugPanels(true).build();
terrain.setRotation(new Quaternion().fromAngleAxis(MathUtils.HALF_PI, Vector3.UNIT_X));
_root.attachChild(terrain);
} catch (final Exception ex1) {
System.out.println("Problem setting up terrain...");
ex1.printStackTrace();
}
skybox = buildSkyBox();
skybox.getSceneHints().setAllPickingHints(false);
_root.attachChild(skybox);
// Setup labels for presenting example info.
final Node textNodes = new Node("Text");
_root.attachChild(textNodes);
textNodes.getSceneHints().setRenderBucketType(RenderBucketType.Ortho);
textNodes.getSceneHints().setLightCombineMode(LightCombineMode.Off);
final double infoStartY = _canvas.getCanvasRenderer().getCamera().getHeight() / 2;
for (int i = 0; i < _exampleInfo.length; i++) {
_exampleInfo[i] = BasicText.createDefaultTextLabel("Text", "", 16);
_exampleInfo[i].setTranslation(new Vector3(10, infoStartY - i * 20, 0));
textNodes.attachChild(_exampleInfo[i]);
}
textNodes.updateGeometricState(0.0);
updateText();
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.U), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
updateTerrain = !updateTerrain;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ONE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(5);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.TWO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(50);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.THREE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(400);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FOUR), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
_controlHandle.setMoveSpeed(1000);
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
groundCamera = !groundCamera;
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.P), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (sphere.getSceneHints().getCullHint() == CullHint.Dynamic) {
sphere.getSceneHints().setCullHint(CullHint.Always);
} else if (sphere.getSceneHints().getCullHint() == CullHint.Always) {
sphere.getSceneHints().setCullHint(CullHint.Dynamic);
}
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.R), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setShowDebug(!terrain.getTextureClipmap().isShowDebug());
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.G), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.reloadShader();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.FIVE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() / 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SIX), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
terrain.getTextureClipmap().setScale(terrain.getTextureClipmap().getScale() * 2);
terrain.reloadShader();
updateText();
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SEVEN), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() + 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.EIGHT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX() - 500.0, camera.getLocation().getY(), camera
.getLocation().getZ());
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.NINE), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() + 500.0);
}
}));
_logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.ZERO), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
final Camera camera = _canvas.getCanvasRenderer().getCamera();
camera.setLocation(camera.getLocation().getX(), camera.getLocation().getY(), camera.getLocation()
.getZ() - 500.0);
}
}));
}
private void setupDefaultStates() {
_lightState.detachAll();
final DirectionalLight dLight = new DirectionalLight();
dLight.setEnabled(true);
dLight.setAmbient(new ColorRGBA(0.4f, 0.4f, 0.5f, 1));
dLight.setDiffuse(new ColorRGBA(0.6f, 0.6f, 0.5f, 1));
dLight.setSpecular(new ColorRGBA(0.3f, 0.3f, 0.2f, 1));
dLight.setDirection(new Vector3(-1, -1, -1).normalizeLocal());
_lightState.attach(dLight);
_lightState.setEnabled(true);
final CullState cs = new CullState();
cs.setEnabled(true);
cs.setCullFace(CullState.Face.Back);
_root.setRenderState(cs);
final FogState fs = new FogState();
fs.setStart(farPlane / 2.0f);
fs.setEnd(farPlane);
fs.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fs.setDensityFunction(DensityFunction.Linear);
_root.setRenderState(fs);
}
/**
* Builds the sky box.
*/
private Skybox buildSkyBox() {
final Skybox skybox = new Skybox("skybox", 10, 10, 10);
final String dir = "images/skybox/";
final Texture north = TextureManager
.load(dir + "1.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture south = TextureManager
.load(dir + "3.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture east = TextureManager.load(dir + "2.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture west = TextureManager.load(dir + "4.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture up = TextureManager.load(dir + "6.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
final Texture down = TextureManager.load(dir + "5.jpg", Texture.MinificationFilter.BilinearNearestMipMap, true);
skybox.setTexture(Skybox.Face.North, north);
skybox.setTexture(Skybox.Face.West, west);
skybox.setTexture(Skybox.Face.South, south);
skybox.setTexture(Skybox.Face.East, east);
skybox.setTexture(Skybox.Face.Up, up);
skybox.setTexture(Skybox.Face.Down, down);
skybox.setRotation(new Quaternion().fromAngleAxis(MathUtils.HALF_PI, Vector3.UNIT_X));
return skybox;
}
/**
* Update text information.
*/
private void updateText() {
_exampleInfo[0].setText("[1/2/3] Moving speed: " + _controlHandle.getMoveSpeed() * 3.6 + " km/h");
_exampleInfo[1].setText("[P] Do picking: " + (sphere.getSceneHints().getCullHint() == CullHint.Dynamic));
_exampleInfo[2].setText("[SPACE] Toggle fly/walk: " + (groundCamera ? "walk" : "fly"));
_exampleInfo[3].setText("[J] Regenerate heightmap/texture");
_exampleInfo[4].setText("[U] Freeze terrain(debug): " + !updateTerrain);
}
}
\ No newline at end of file diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/BMFontLoader.java b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/BMFontLoader.java index 73be066..0803578 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/BMFontLoader.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/BMFontLoader.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -25,7 +25,7 @@ public class BMFontLoader { static Logger logger = Logger.getLogger(BMFontLoader.class.getName()); static BMFontLoader s_instance = null; - final ArrayList<BMFont> _fontList = new ArrayList<BMFont>(); + final ArrayList<BMFont> _fontList = new ArrayList<>(); public static List<BMFont> allFonts() { return instance()._fontList; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/BMTextExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/BMTextExample.java index dc2b588..96ba209 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/BMTextExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/BMTextExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -184,6 +184,7 @@ public class BMTextExample extends ExampleBase { final int changeInterval = 20000; final List<BMFont> fonts = BMFontLoader.allFonts(); + @Override public void update(final double time, final BMText text) { final int t = (int) (System.currentTimeMillis() / changeInterval); final int index = t % fonts.size(); @@ -216,6 +217,7 @@ public class BMTextExample extends ExampleBase { final SpatialController<Node> nodeMover = new SpatialController<Node>() { Matrix3 rot = new Matrix3(); + @Override public void update(final double time, final Node caller) { final long t = System.currentTimeMillis(); final double s = Math.cos(t * Math.PI / 10000.0); diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/InteractUIExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/InteractUIExample.java index 45a3478..2bc3de0 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/InteractUIExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/InteractUIExample.java @@ -77,14 +77,13 @@ import com.ardor3d.scenegraph.shape.Tube; import com.ardor3d.scenegraph.visitor.Visitor; import com.ardor3d.util.ReadOnlyTimer; import com.ardor3d.util.TextureManager; -import com.google.common.collect.Lists; /** * An example illustrating the use of the interact framework. */ @Purpose(htmlDescriptionKey = "com.ardor3d.example.interact.InteractUIExample", // -thumbnailPath = "com/ardor3d/example/media/thumbnails/interact_InteractUIExample.jpg", // -maxHeapMemory = 64) + thumbnailPath = "com/ardor3d/example/media/thumbnails/interact_InteractUIExample.jpg", // + maxHeapMemory = 64) public class InteractUIExample extends ExampleBase { final UIHud hud = new UIHud(); @@ -162,7 +161,7 @@ public class InteractUIExample extends ExampleBase { _root.updateGeometricState(0); } - LinkedList<Spatial> path = Lists.newLinkedList(); + LinkedList<Spatial> path = new LinkedList<>(); private void initPath() { final Spatial marker1 = createMarker(); @@ -205,6 +204,7 @@ public class InteractUIExample extends ExampleBase { t.addController(new SpatialController<Spatial>() { private double _scaleTime = 0; + @Override public void update(final double time, final Spatial caller) { // update our rotation final double pulseSpeed = ((MarkerData) t.getUserData()).pulseSpeed; @@ -296,43 +296,43 @@ public class InteractUIExample extends ExampleBase { manager.setActiveWidget(moveWidget); // add triggers to change which widget is active - manager.getLogicalLayer().registerTrigger( - new InputTrigger(new KeyReleasedCondition(Key.ONE), new TriggerAction() { + manager.getLogicalLayer() + .registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.ONE), new TriggerAction() { @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { manager.setActiveWidget(moveWidget); } })); - manager.getLogicalLayer().registerTrigger( - new InputTrigger(new KeyReleasedCondition(Key.TWO), new TriggerAction() { + manager.getLogicalLayer() + .registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.TWO), new TriggerAction() { @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { manager.setActiveWidget(insertWidget); } })); - manager.getLogicalLayer().registerTrigger( - new InputTrigger(new KeyReleasedCondition(Key.THREE), new TriggerAction() { + manager.getLogicalLayer() + .registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.THREE), new TriggerAction() { @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { manager.setActiveWidget(colorWidget); } })); - manager.getLogicalLayer().registerTrigger( - new InputTrigger(new KeyReleasedCondition(Key.FOUR), new TriggerAction() { + manager.getLogicalLayer() + .registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.FOUR), new TriggerAction() { @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { manager.setActiveWidget(pulseWidget); } })); - manager.getLogicalLayer().registerTrigger( - new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { + manager.getLogicalLayer() + .registerTrigger(new InputTrigger(new KeyPressedCondition(Key.SPACE), new TriggerAction() { @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { showMenu(); } })); - manager.getLogicalLayer().registerTrigger( - new InputTrigger(new KeyReleasedCondition(Key.SPACE), new TriggerAction() { + manager.getLogicalLayer() + .registerTrigger(new InputTrigger(new KeyReleasedCondition(Key.SPACE), new TriggerAction() { @Override public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) { hideMenu(); @@ -576,8 +576,8 @@ public class InteractUIExample extends ExampleBase { centerPanel.setBackdrop(new EmptyBackdrop()); centerPanel.setLayoutData(BorderLayoutData.CENTER); - final UIComboBox combo = new UIComboBox(new DefaultComboBoxModel("White", "Black", "Red", "Green", "Blue", - "Yellow", "Magenta", "Cyan")); + final UIComboBox combo = new UIComboBox( + new DefaultComboBoxModel("White", "Black", "Red", "Green", "Blue", "Yellow", "Magenta", "Cyan")); combo.setLocalComponentWidth(100); combo.addSelectionListener(new SelectionListener<UIComboBox>() { @Override diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/RotatingUIExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/RotatingUIExample.java index 8251e99..d7e10d9 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/RotatingUIExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/RotatingUIExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -94,6 +94,7 @@ public class RotatingUIExample extends ExampleBase { rotatingLabel.addController(new SpatialController<UICheckBox>() { double angle = 0; + @Override public void update(final double time, final UICheckBox caller) { angle += time * 10; angle %= 360; diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/SimpleUIExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/SimpleUIExample.java index 8c756e5..8cf69fc 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/ui/SimpleUIExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/ui/SimpleUIExample.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2008-2012 Ardor Labs, Inc. + * Copyright (c) 2008-2014 Ardor Labs, Inc. * * This file is part of Ardor3D. * @@ -90,6 +90,7 @@ public class SimpleUIExample extends ExampleBase { private double angle = 0; private final Vector3 axis = new Vector3(1, 1, 0.5f).normalizeLocal(); + @Override public void update(final double time, final Box caller) { angle += time * 50; angle %= 360; @@ -171,6 +172,7 @@ public class SimpleUIExample extends ExampleBase { tfPassword.setLayoutData(GridLayoutData.WrapAndGrow); final UIButton btLogin = new UIButton("login"); btLogin.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { System.out.println("login as user: " + tfName.getText() + " password: " + tfPassword.getText()); } @@ -202,6 +204,7 @@ public class SimpleUIExample extends ExampleBase { chatButton.setLayoutData(BorderLayoutData.EAST); final ActionListener actionListener = new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { applyChat(historyArea, chatField); } @@ -271,6 +274,7 @@ public class SimpleUIExample extends ExampleBase { final UILabel lSliderValue = new UILabel("0"); lSliderValue.setLayoutData(GridLayoutData.SpanAndWrap(2)); slider.addActionListener(new ActionListener() { + @Override public void actionPerformed(final ActionEvent event) { lSliderValue.setText(String.valueOf(slider.getValue())); } @@ -333,6 +337,7 @@ public class SimpleUIExample extends ExampleBase { multiImgBD.addImage(minute); clockPanel.addController(new SpatialController<Spatial>() { + @Override public void update(final double time, final Spatial caller) { final double angle1 = _timer.getTimeInSeconds() % MathUtils.TWO_PI; final double angle2 = (_timer.getTimeInSeconds() / 12.) % MathUtils.TWO_PI; diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/i18n/example_descriptions.properties b/ardor3d-examples/src/main/resources/com/ardor3d/example/i18n/example_descriptions.properties index fad9b46..9b681f3 100644 --- a/ardor3d-examples/src/main/resources/com/ardor3d/example/i18n/example_descriptions.properties +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/i18n/example_descriptions.properties @@ -1,12 +1,10 @@ com.ardor3d.example.NotSet=... com.ardor3d.example.basic.BoxExample=A simple example showing a textured and lit box spinning. -com.ardor3d.example.basic.JoglBasicExample=This jogl-based example is meant to show how to use Ardor3D at the most primitive level. -com.ardor3d.example.basic.LineExample=A demonstration of antialising on a Line object. -com.ardor3d.example.basic.LwjglBasicExample=This lwjgl-based example is meant to show how to use Ardor3D at the most primitive level. -com.ardor3d.example.basic.LwjglHeadlessExample=A demonstration of the LwjglHeadlessCanvas class, which is canvas used to draw Scene data to an offscreen target. +com.ardor3d.example.basic.JoglBasicExample=This JOGL-based example is meant to show how to use Ardor3D at the most primitive level. It uses NEWT. +com.ardor3d.example.basic.LineExample=A demonstration of anti-aliasing on a Line object. com.ardor3d.example.basic.MatrixLookAtExample=A demonstration of the MathUtils.matrixLookAt function, which constructs a rotation matrix used to orient a source position to a given target position. -com.ardor3d.example.basic.MouseManagerExample=A demonstration of the MouseManager class, which is used to control properties (e.g. curser, location) of the native mouse. +com.ardor3d.example.basic.MouseManagerExample=A demonstration of the MouseManager class, which is used to control properties (e.g. cursor, location) of the native mouse. com.ardor3d.example.basic.OrbitCamExample=A demonstration of the OrbitCamControl, a controller that can position a camera in an orbit around a given target - in this case, a teapot. com.ardor3d.example.basic.RTTShaderExample=A simple example showing use of shaders inside of RTT. com.ardor3d.example.basic.ShapesExample=A display of intrinsic shapes (e.g. Box, Cone, Torus). @@ -15,12 +13,14 @@ com.ardor3d.example.benchmark.ball.BubbleMarkExample=The famous BubbleMark UI te com.ardor3d.example.benchmark.ball.BubbleMarkUIExample=The famous BubbleMark UI test, recreated using Ardor3D UI components. com.ardor3d.example.canvas.JoglAwtExample=This examples demonstrates how to render OpenGL (via JOGL) on a AWT canvas. com.ardor3d.example.canvas.JoglAwtDesktopExample=This examples demonstrates how to render OpenGL (via JOGL) inside JDesktop internal frames. +com.ardor3d.example.canvas.JoglNewtAwtExample=This example demonstrates how to render OpenGL (via JOGL) on a NEWT AWT canvas. +com.ardor3d.example.canvas.JoglNewtSwtExample=This example demonstrates how to render OpenGL (via JOGL) on a NEWT SWT canvas. com.ardor3d.example.canvas.JoglSwtExample=This examples demonstrates how to render OpenGL (via JOGL) in a SWT canvas. -com.ardor3d.example.canvas.LwjglAwtExample=This examples demonstrates how to render OpenGL (via LWJGL) on a AWT canvas. -com.ardor3d.example.canvas.LwjglSwtExample=This examples demonstrates how to render OpenGL (via LWJGL) on a SWT canvas. -com.ardor3d.example.collision.CollisionTreeExample=A demonstration of finding and retrieving collisions between two nodes +com.ardor3d.example.canvas.JoglSwingExample=This example demonstrates how to render OpenGL (via JOGL) on a Swing panel. +com.ardor3d.example.collision.CollisionTreeExample=A demonstration of finding and retrieving collisions between two nodes. com.ardor3d.example.collision.ManyCollisionsExample=A demonstration on how to determine if collisions exist between two nodes. com.ardor3d.example.effect.BloomExample=A simple example showing bloom. +com.ardor3d.example.effect.ExtrusionExample=A demonstration of extrusion, showing how a set of point can be converted into a 3d shape. com.ardor3d.example.effect.NewDynamicSmokerExample=Another particle demonstration, this one showing a smoking rocket following the cursor around the screen. com.ardor3d.example.effect.ParallelSplitShadowMapExample=Example showing the parallel split shadow mapping technique. Requires GLSL support. com.ardor3d.example.effect.ParticleRampExample=A demonstration of the ParticleSystem and RampEntry classes; which controls how an emitter's properties (e.g. size, color) change over time. @@ -32,11 +32,14 @@ com.ardor3d.example.effect.ProjectedGridWaterExample=A demonstration of the Wate com.ardor3d.example.effect.QuadImposterExample=A demonstration of the QuadImposterNode class; which sets the texture level of detail for a Node. com.ardor3d.example.effect.TrailExample=An example of using TrailMesh. com.ardor3d.example.effect.WaterExample=A demonstration of the WaterNode class; which handles rendering of a water effect on all of it's children. +com.ardor3d.example.interact.InteractExample=An example illustrating the use of the interact framework +com.ardor3d.example.interact.TerrainInteractExample=Example showing interact widgets with the Geometry Clipmap Terrain system. Requires GLSL support. com.ardor3d.example.interpolation.CurveInterpolationControllerExample=A demonstration of the CurveInterpolationController class; which will move/translate a Node each epoch through a set of 3D coordinates (via spline). com.ardor3d.example.interpolation.DefaultColorInterpolationControllerExample=A demonstration of the DefaultColorInterpolationController class; which updates the default colour each epoch by interpolating between the given colours. com.ardor3d.example.interpolation.LinearVector3InterpolationControllerExample=A demonstration of the LinearVector3InterpolationController class; which will move a Node through a set of 3D coordinates (via linear interpolation). com.ardor3d.example.interpolation.QuaternionInterpolationControllerExample=A demonstration of the QuaternionInterpolationController class; which will rotate a Node each epoch by interpolating between the given quaternions. com.ardor3d.example.pipeline.AnimationBlinnPhongExample=Illustrates gpu skinning with normal map, specular map and diffuse coloring. +com.ardor3d.example.pipeline.AnimationCopyExample=Illustrates loading several animations from Collada and arranging them in an animation state machine. com.ardor3d.example.pipeline.AnimationDemoExample=Illustrates loading several animations from Collada and arranging them in a controllable blend tree. com.ardor3d.example.pipeline.AnimationStateExample=Adds play/pause/stop controls to AnimationDemoExample. com.ardor3d.example.pipeline.ColladaExample=Illustrates loading a model from Collada. If the model also contains an animation, the animation is played as well. @@ -45,6 +48,7 @@ com.ardor3d.example.pipeline.ExportImportExample=A demonstration of the BinaryIm com.ardor3d.example.pipeline.PrimitiveSkeletonExample=A demonstration of combining the skeletal animation classes with OpenGL Shading Language. com.ardor3d.example.pipeline.SimpleColladaExample=Simplest example of loading a Collada model. com.ardor3d.example.pipeline.SimpleMd2Example=Simplest example of loading a model in MD2 format. +com.ardor3d.example.pipeline.SimpleMd3Example=Simplest example of loading a model in MD3 format. com.ardor3d.example.pipeline.SimpleObjExample=Simplest example of loading a Wavefront OBJ model. com.ardor3d.example.renderer.BillboardNodeExample=Illustrates the BillboardNode class; which defines a node that always orients towards the camera. com.ardor3d.example.renderer.BillboardNodeZExample=Illustrates the BillboardNode class - but using a Z-up camera. @@ -64,21 +68,25 @@ com.ardor3d.example.renderer.MultiPassTextureExample=Borrows from the BoxExample com.ardor3d.example.renderer.MultiStripExample=Illustrates mesh with several primitives (i.e. strip, quad, triangle). com.ardor3d.example.renderer.PointCubeExample=A more complex example of using geometry shaders. Requires support for geometry shaders (obviously). com.ardor3d.example.renderer.PointsExample=A simple demonstration of displaying numerous Point in three-dimensions. +com.ardor3d.example.renderer.RenderEffectsExample=A simple example illustrating use of RenderEffects. com.ardor3d.example.renderer.RenderQueueExample=Illustrates the Render Queue, which controls how Nodes are drawn when overlapping occurs. +com.ardor3d.example.renderer.RenderTextureCubeMapExample=Demonstrates rendering to texture, where the texture is a cubemap. com.ardor3d.example.renderer.RenderTextureSideBySideExample=Illustrates the TextureRenderer class; which renders a scene to a buffer and copying it to a texture. com.ardor3d.example.renderer.SphereComparisonsExample=Simple example showing differences between GeoSphere and Sphere and their various texture mappings. com.ardor3d.example.renderer.StereoExample=Illustrates the StereoCamera class, which allows for your stereo viewing pleasures. com.ardor3d.example.renderer.TexCombineExample=Shows interpolated textures using texture combine. com.ardor3d.example.renderer.Texture3DExample=Very simple example showing use of a Texture3D texture. -com.ardor3d.example.renderer.TextureClipmapExample=Illustrates the TextureClipmap class, which prohibits the display of textures outside a defined region. com.ardor3d.example.renderer.TextureProjectionExample=Illustrates the TextureProjector class, which projects a two-dimensional texture onto a three-dimensional surface. com.ardor3d.example.renderer.UpdateTextureExample=A demonstration of procedurally updating a texture. com.ardor3d.example.renderer.VBOSpeedExample=Illustrates the DataMode class, which describe how we prefer data to be sent to the card. com.ardor3d.example.renderer.ViewportExample=Illustrates the Camera class, which represents a view into a 3d scene and how that view should map to a 2D rendering surface. com.ardor3d.example.renderer.WireframeGeometryShaderExample=An example of using geometry shaders. Requires support for geometry shaders (obviously). +com.ardor3d.example.renderer.utils.atlas.AtlasExample=Example showing how to use the TexturePacker to create a texture atlas. Also shows the benefits of using it together with the MeshCombiner. +com.ardor3d.example.renderer.utils.atlas.AtlasExampleMultiTextured=Example showing how to use the TexturePacker to create a texture atlas. Also shows the benefits of using it together with the MeshCombiner. com.ardor3d.example.terrain.ArrayTerrainExample=Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a float array. Requires GLSL support. com.ardor3d.example.terrain.ImageMapTerrainExample=Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a float array populated from a heightmap generated from an Image. Requires GLSL support. com.ardor3d.example.terrain.InMemoryTerrainExample=Example showing the Geometry Clipmap Terrain system with 'MegaTextures' streaming from an in-memory data source. Requires GLSL support. +com.ardor3d.example.terrain.MountainShadowTerrainExample=Example showing the Geometry Clipmap Terrain system with 'MegaTextures' where the terrain data is provided from a float array populated from a heightmap generated from an Image. Requires GLSL support. com.ardor3d.example.terrain.ProceduralTerrainExample=Example showing the Geometry Clipmap Terrain system with 'MegaTextures' using content procedurally generated on-the-fly. Requires GLSL support. com.ardor3d.example.terrain.ShadowedTerrainExample=Example showing the Geometry Clipmap Terrain system combined with PSSM. (a bit experimental) Requires GLSL support. com.ardor3d.example.terrain.ShapesPlusProceduralTerrainExample=Example showing the Geometry Clipmap Terrain system with 'MegaTextures'. We merge AWT drawing with the terrain texture in real time. Requires GLSL support. diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.jpg b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.jpg Binary files differnew file mode 100644 index 0000000..9bda495 --- /dev/null +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.jpg diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.md3 b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.md3 Binary files differnew file mode 100644 index 0000000..1a8ce49 --- /dev/null +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.md3 diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.qc b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.qc new file mode 100644 index 0000000..54b95f6 --- /dev/null +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/md3/barrel1.qc @@ -0,0 +1,19 @@ +// Quake III Arena MD3 control file, generated by MilkShape 3D +// +$model "models/furniture/barrel1.md3" +// reference frame +//$frames -1 -1 +// frame 1-30 +$frames 1 30 +$flags 0 +$numskins 0 + +// you can have one or no parent tag + +// tags + +// meshes (surfaces) +$mesh "barrel" +$skin "models/furniture/barrel1.jpg" +$flags 0 + diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/ply/big_spider.ply b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/ply/big_spider.ply new file mode 100644 index 0000000..96b77c4 --- /dev/null +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/ply/big_spider.ply @@ -0,0 +1,13965 @@ +ply +format ascii 1.0 +element vertex 4670 +property float32 x +property float32 y +property float32 z +element face 9286 +property list uint8 int32 vertex_indices +end_header +1.8057 2.0344 1.6154 +1.8145 2.0406 1.5811 +1.8233 2.0216 1.6105 +1.849 2.0394 1.6526 +1.8312 2.0523 1.6575 +1.8711 2.0802 1.7022 +1.8815 2.0726 1.6992 +1.9169 2.1004 1.7385 +1.905 2.104 1.7444 +1.903 2.1026 1.7601 +1.9157 2.0932 1.7563 +1.9205 2.0865 1.77 +1.9009 2.1011 1.7758 +1.9884 2.1623 1.8924 +2.003 2.1513 1.8879 +2.0806 2.2269 2.0045 +2.0825 2.2282 2.0264 +2.1001 2.2144 2.0203 +2.1097 2.2095 2.0395 +2.0843 2.2295 2.0483 +2.1748 2.2929 2.1339 +2.1973 2.2739 2.1247 +2.2993 2.3556 2.1762 +2.2844 2.3696 2.1834 +2.4019 2.4519 2.2117 +2.4121 2.4389 2.2049 +2.4389 2.4393 2.2227 +2.4198 2.4644 2.2357 +2.4379 2.4771 2.2587 +2.4656 2.4399 2.2395 +2.5974 2.5332 2.2219 +2.5739 2.5723 2.2407 +2.7002 2.6608 2.1681 +2.7184 2.6222 2.1522 +2.8259 2.7016 2.0466 +2.8126 2.7395 2.0584 +2.9128 2.8096 1.9201 +2.9236 2.7732 1.9112 +2.9996 2.8296 1.7579 +2.9908 2.8642 1.7639 +3.0408 2.8993 1.5918 +3.0484 2.8668 1.5886 +3.0065 2.8752 1.581 +1.842 2.0242 1.5987 +1.8678 2.042 1.6406 +1.8976 2.0839 1.6847 +1.9289 2.0949 1.7472 +1.9411 2.0892 1.7559 +2.0182 2.1532 1.8769 +2.1048 2.2292 1.9847 +2.118 2.2161 2.0056 +2.1355 2.2119 2.0183 +2.2188 2.2746 2.1024 +2.3117 2.3542 2.1585 +2.4178 2.4346 2.1886 +2.4486 2.4302 2.1914 +2.4794 2.4261 2.1933 +2.6019 2.5134 2.1768 +2.7137 2.5977 2.1141 +2.8135 2.6734 2.0183 +2.9085 2.7444 1.8894 +2.9828 2.8009 1.743 +3.0312 2.8391 1.5809 +1.851 2.041 1.5869 +1.8767 2.0588 1.6285 +1.9177 2.1128 1.7326 +1.9351 2.1068 1.7381 +1.9506 2.1076 1.7417 +2.0251 2.1668 1.8659 +2.1256 2.2323 1.9909 +2.1465 2.2353 1.9971 +2.2268 2.2946 2.0801 +2.3147 2.3664 2.1408 +2.4156 2.4414 2.1723 +2.4433 2.4424 2.16 +2.4712 2.4437 2.147 +2.5847 2.5244 2.1319 +2.6891 2.6018 2.076 +2.7828 2.6714 1.99 +2.8763 2.7401 1.8675 +2.9501 2.795 1.728 +2.9993 2.8324 1.5732 +1.8449 2.0619 1.5821 +1.8706 2.0799 1.6236 +1.8941 2.0963 1.6818 +1.9305 2.1218 1.7343 +1.9436 2.131 1.7359 +2.0197 2.1843 1.8614 +2.091 2.2488 1.9847 +2.1186 2.2535 1.9848 +2.1364 2.266 1.9883 +2.2166 2.3221 2.071 +2.3066 2.3852 2.1336 +2.4069 2.4554 2.1656 +2.4263 2.4689 2.147 +2.4457 2.4826 2.1278 +2.556 2.5598 2.1132 +2.6592 2.632 2.0602 +2.7517 2.6968 1.9782 +2.8458 2.7627 1.8587 +2.9206 2.8151 1.7221 +2.9714 2.8507 1.57 +1.8273 2.0747 1.5869 +1.8529 2.0928 1.6285 +1.8836 2.1039 1.6847 +1.9058 2.1164 1.7385 +1.9179 2.1312 1.7381 +1.924 2.1456 1.7417 +2.0051 2.1953 1.8659 +2.101 2.2674 1.9909 +2.1111 2.286 1.9971 +2.1942 2.3411 2.0801 +2.2917 2.3992 2.1408 +2.3967 2.4684 2.1723 +2.4072 2.494 2.16 +2.4179 2.5198 2.147 +2.5326 2.5988 2.1319 +2.641 2.6705 2.076 +2.7385 2.7347 1.99 +2.835 2.7991 1.8675 +2.9118 2.8497 1.728 +2.9638 2.8831 1.5732 +1.8086 2.0721 1.5987 +1.834 2.0902 1.6406 +1.8675 2.0926 1.6992 +1.9047 2.1295 1.7472 +1.9034 2.1429 1.7559 +1.99 2.1935 1.8769 +2.0767 2.2388 2.0011 +2.0832 2.2657 2.0056 +2.0853 2.2836 2.0183 +2.1727 2.3405 2.1024 +2.2793 2.4006 2.1585 +2.3911 2.4727 2.1886 +2.3975 2.5032 2.1914 +2.4042 2.5336 2.1933 +2.5281 2.6188 2.1768 +2.6456 2.695 2.1141 +2.7508 2.7629 2.0183 +2.8501 2.8279 1.8893 +2.9286 2.8784 1.743 +2.981 2.9108 1.5809 +1.7996 2.0553 1.6105 +1.8252 2.0734 1.6526 +1.8985 2.1176 1.7563 +1.8939 2.1245 1.77 +1.983 2.1798 1.8879 +2.0755 2.2495 2.0203 +2.0742 2.2602 2.0395 +2.1647 2.3205 2.1247 +2.2763 2.3884 2.1762 +2.3932 2.4659 2.2049 +2.4028 2.491 2.2227 +2.4124 2.5159 2.2395 +2.5452 2.6078 2.2219 +2.6702 2.6911 2.1522 +2.7815 2.7649 2.0466 +2.8822 2.8322 1.9112 +2.9613 2.8844 1.7579 +3.0129 2.9175 1.5886 +2.6712 2.7678 1.3512 +2.6887 2.7207 1.2899 +2.6671 2.7781 1.34 +2.5841 2.7334 1.3396 +2.6634 2.7866 1.2952 +2.5864 2.7508 1.2828 +2.4965 2.7147 1.3142 +2.5069 2.7276 1.2697 +2.4259 2.7176 1.2458 +2.4129 2.7137 1.2733 +2.6634 2.7865 1.285 +2.6663 2.7778 1.2398 +2.5924 2.7454 1.2436 +2.518 2.7217 1.23 +2.4366 2.7205 1.2227 +2.6702 2.7674 1.2275 +2.5957 2.7374 1.2326 +2.688 2.7208 1.2179 +2.6035 2.7006 1.221 +2.5192 2.7019 1.2186 +2.7061 2.6738 1.2274 +2.6102 2.6584 1.2295 +2.5155 2.6666 1.2327 +2.7106 2.6623 1.2386 +2.6106 2.6483 1.2389 +2.7147 2.6529 1.2885 +2.6094 2.639 1.2827 +2.509 2.6593 1.2675 +2.7114 2.6626 1.3388 +2.6026 2.6456 1.3268 +2.4981 2.6664 1.3118 +2.7071 2.6742 1.3511 +2.6001 2.6551 1.338 +2.6892 2.721 1.3607 +2.591 2.6926 1.3491 +2.4953 2.6874 1.3226 +2.6261 2.8917 1.3512 +2.5373 2.862 1.3396 +2.6296 2.8811 1.34 +2.6092 2.939 1.2899 +2.3935 2.7671 1.2733 +2.406 2.7724 1.2458 +2.4744 2.8168 1.2697 +2.4582 2.82 1.3142 +2.5502 2.8502 1.2828 +2.6323 2.8723 1.2952 +2.6322 2.8723 1.285 +2.4161 2.7771 1.2227 +2.4791 2.8285 1.23 +2.5514 2.8581 1.2436 +2.6288 2.8808 1.2398 +2.5488 2.8664 1.2326 +2.6251 2.8913 1.2275 +2.4673 2.8444 1.2186 +2.531 2.8996 1.221 +2.6088 2.9384 1.2179 +2.4418 2.869 1.2327 +2.5029 2.9442 1.2389 +2.5925 2.986 1.2274 +2.5885 2.9978 1.2386 +2.4321 2.8705 1.2675 +2.496 2.9505 1.2827 +2.5856 3.0076 1.2885 +2.4284 2.8581 1.3118 +2.495 2.9412 1.3268 +2.5893 2.9981 1.3388 +2.4992 2.9322 1.338 +2.5935 2.9864 1.3511 +2.4397 2.8401 1.3226 +2.5164 2.8977 1.3491 +2.6099 2.9391 1.3607 +2.8803 2.6425 1.7478 +2.9006 2.6499 1.7989 +2.8892 2.6183 1.7547 +2.8446 2.5907 1.7365 +2.8321 2.625 1.7267 +2.7839 2.6074 1.7478 +2.7927 2.5832 1.7547 +2.7636 2.6 1.7989 +2.8956 2.6006 1.7735 +2.8537 2.5656 1.7631 +2.7992 2.5655 1.7735 +2.898 2.5941 1.7993 +2.8571 2.5565 1.7996 +2.8015 2.559 1.7993 +2.8957 2.6005 1.825 +2.8537 2.5656 1.8361 +2.7992 2.5654 1.825 +2.8892 2.6183 1.844 +2.8446 2.5907 1.8627 +2.7927 2.5832 1.844 +2.8804 2.6425 1.8509 +2.8321 2.625 1.8725 +2.7839 2.6074 1.8509 +2.8716 2.6668 1.844 +2.8197 2.6592 1.8627 +2.775 2.6317 1.844 +2.8651 2.6845 1.825 +2.8105 2.6843 1.8361 +2.7686 2.6494 1.825 +2.8628 2.691 1.7993 +2.8072 2.6935 1.7996 +2.7663 2.6558 1.7993 +2.8651 2.6844 1.7735 +2.8105 2.6843 1.7631 +2.7687 2.6493 1.7735 +2.8715 2.6667 1.7547 +2.8197 2.6592 1.7365 +2.7751 2.6316 1.7547 +2.6094 3.087 1.7478 +2.5891 3.0796 1.7989 +2.6006 3.1111 1.7547 +2.6451 3.1387 1.7365 +2.6576 3.1045 1.7267 +2.7058 3.122 1.7478 +2.697 3.1462 1.7547 +2.7261 3.1294 1.7989 +2.5941 3.1289 1.7735 +2.636 3.1638 1.7631 +2.6906 3.164 1.7735 +2.5917 3.1354 1.7993 +2.6327 3.173 1.7996 +2.6882 3.1705 1.7993 +2.5941 3.1289 1.825 +2.636 3.1638 1.8361 +2.6906 3.1641 1.825 +2.6005 3.1112 1.844 +2.6451 3.1387 1.8627 +2.697 3.1463 1.844 +2.6093 3.0869 1.8509 +2.6576 3.1045 1.8725 +2.7059 3.1221 1.8509 +2.6182 3.0627 1.844 +2.6701 3.0702 1.8627 +2.7147 3.0978 1.844 +2.6246 3.0449 1.825 +2.6792 3.0452 1.8361 +2.7211 3.0801 1.825 +2.627 3.0385 1.7993 +2.6825 3.036 1.7996 +2.7235 3.0736 1.7993 +2.6246 3.045 1.7735 +2.6792 3.0452 1.7631 +2.7211 3.0801 1.7735 +2.6182 3.0628 1.7547 +2.6701 3.0702 1.7365 +2.7146 3.0978 1.7547 +2.6043 2.7587 1.2668 +2.581 2.8035 1.2893 +2.6007 2.7714 1.2592 +2.6309 2.7459 1.2343 +2.6378 2.7176 1.2599 +2.6795 2.6839 1.2635 +2.6692 2.728 1.2148 +2.7133 2.7189 1.2007 +2.7274 2.661 1.2724 +2.7795 2.6527 1.2816 +2.7606 2.7196 1.1922 +2.809 2.7313 1.1893 +2.834 2.6625 1.2857 +2.8795 2.6905 1.2859 +2.8548 2.7557 1.1942 +2.8944 2.7886 1.206 +2.9156 2.7313 1.2863 +2.9483 2.7772 1.2868 +2.9317 2.825 1.2206 +2.9709 2.8595 1.2335 +2.9838 2.8205 1.2873 +3.0283 2.8535 1.2876 +3.016 2.887 1.2406 +3.0911 2.9224 1.2457 +3.1021 2.8924 1.2877 +3.1751 2.9328 1.288 +3.1657 2.9587 1.2516 +3.241 2.9937 1.2564 +3.2492 2.9711 1.2881 +3.4348 3.0579 1.2884 +3.4286 3.0749 1.2646 +3.5899 3.1433 1.2708 +3.5946 3.1306 1.2886 +3.7144 3.185 1.2888 +3.7076 3.2038 1.2681 +3.704 3.2135 1.2893 +2.5978 2.7793 1.2459 +2.6254 2.7609 1.2119 +2.6615 2.7491 1.1866 +2.7038 2.7448 1.1694 +2.7501 2.7486 1.1596 +2.798 2.7614 1.1565 +2.8444 2.7842 1.163 +2.8852 2.8136 1.1787 +2.9242 2.8456 1.198 +2.9648 2.8763 1.2152 +3.0107 2.9017 1.2246 +3.0864 2.9355 1.2314 +3.1616 2.9701 1.2392 +3.2374 3.0036 1.2456 +3.4227 3.0913 1.2516 +3.5855 3.1556 1.261 +2.5922 2.7947 1.2449 +2.6161 2.7866 1.2074 +2.6499 2.781 1.1773 +2.6911 2.7798 1.1551 +2.737 2.7847 1.1413 +2.7848 2.7976 1.1366 +2.8318 2.8187 1.1441 +2.8742 2.8438 1.1622 +2.9152 2.8706 1.1844 +2.9576 2.8965 1.2041 +3.0043 2.9193 1.2149 +3.0806 2.9513 1.2227 +3.1566 2.9838 1.2317 +3.233 3.0155 1.2391 +2.5881 2.8066 1.2456 +2.6064 2.8151 1.2076 +2.6342 2.8277 1.1761 +2.6695 2.8431 1.1524 +2.7107 2.8601 1.1374 +2.7558 2.8773 1.1322 +2.8039 2.8944 1.1399 +2.85 2.9101 1.1585 +2.8954 2.9254 1.1813 +2.9417 2.9411 1.2016 +2.9901 2.9582 1.2127 +3.068 2.9861 1.2208 +3.1457 3.0138 1.23 +3.2235 3.0418 1.2376 +3.4155 3.1109 1.2505 +3.5801 3.1703 1.2602 +3.7035 3.2148 1.2675 +2.5834 2.8182 1.243 +2.5945 2.8434 1.2048 +2.6142 2.8747 1.1749 +2.6426 2.9077 1.1532 +2.6797 2.938 1.1401 +2.7253 2.9612 1.1357 +2.7753 2.9743 1.1433 +2.8247 2.98 1.1614 +2.8741 2.983 1.1837 +2.9241 2.9878 1.2036 +2.9753 2.9991 1.2144 +3.0546 3.0227 1.2223 +3.1341 3.0455 1.2313 +3.2134 3.0694 1.2388 +3.408 3.1316 1.2514 +3.5745 3.1858 1.2609 +3.6958 3.2362 1.2753 +2.5767 2.8367 1.243 +2.5836 2.8733 1.208 +2.6011 2.9107 1.1829 +2.6287 2.946 1.1665 +2.6656 2.9765 1.1576 +2.7114 2.9994 1.1549 +2.7623 3.0107 1.1614 +2.8132 3.0119 1.1773 +2.8644 3.0092 1.1969 +2.9161 3.0091 1.2142 +2.9685 3.0177 1.2238 +3.0486 3.0393 1.2307 +3.1289 3.0599 1.2386 +3.2089 3.0819 1.2451 +3.4017 3.1488 1.2644 +3.5698 3.1987 1.2706 +2.5736 2.8452 1.2574 +2.5778 2.8894 1.2319 +2.593 2.9331 1.2125 +2.6188 2.9732 1.199 +2.6546 3.0068 1.191 +2.6999 3.0308 1.1884 +2.7516 3.0407 1.1933 +2.8037 3.0381 1.2053 +2.8564 3.0308 1.2199 +2.9095 3.0265 1.233 +2.9629 3.033 1.2401 +3.0436 3.053 1.2453 +3.1245 3.0718 1.2512 +3.2051 3.0923 1.2561 +2.5677 2.8586 1.2666 +2.5641 2.917 1.2604 +2.5718 2.9745 1.2652 +2.5919 3.0268 1.2754 +2.6259 3.0696 1.2856 +2.6752 3.0987 1.2902 +2.729 3.1057 1.2901 +2.7835 3.095 1.29 +2.8385 3.0775 1.2899 +2.8943 3.0642 1.2898 +2.9508 3.0661 1.2897 +3.0328 3.0827 1.2897 +3.1152 3.0974 1.2896 +3.197 3.1146 1.2896 +3.3956 3.1656 1.2895 +3.5652 3.2113 1.2895 +3.6924 3.2456 1.2894 +2.5631 2.8711 1.2868 +2.5588 2.9284 1.2919 +2.5651 2.9871 1.3209 +2.5836 3.0427 1.3531 +2.6149 3.0945 1.3769 +2.6595 3.1418 1.381 +2.7159 3.1477 1.3766 +2.7708 3.1321 1.3658 +2.8258 3.1081 1.3525 +2.8826 3.0889 1.3405 +2.9429 3.0881 1.3337 +3.0257 3.1023 1.329 +3.1089 3.1144 1.3237 +3.1916 3.1294 1.3193 +3.3916 3.1767 1.3118 +3.5622 3.2196 1.3062 +3.6901 3.2518 1.3019 +2.5586 2.9312 1.3228 +2.5659 2.9879 1.3786 +2.5839 3.0452 1.4353 +2.6112 3.1071 1.474 +2.6465 3.1776 1.4759 +2.7055 3.1824 1.467 +2.7606 3.162 1.4453 +2.8153 3.1319 1.4186 +2.8729 3.1076 1.3943 +2.9369 3.1046 1.3803 +3.0204 3.1171 1.3707 +3.1041 3.1271 1.3597 +3.1875 3.1406 1.3507 +3.3886 3.1851 1.3353 +3.5599 3.2259 1.3238 +3.6884 3.2565 1.3152 +2.5487 2.9042 1.3317 +2.5435 2.9649 1.3883 +2.549 3.0207 1.4599 +2.5682 3.0718 1.5285 +2.5982 3.1297 1.5814 +2.6363 3.2058 1.6061 +2.6983 3.2084 1.5902 +2.7539 3.181 1.5516 +2.8081 3.1438 1.5043 +2.8663 3.115 1.4619 +2.9345 3.111 1.437 +3.0184 3.1228 1.4213 +3.1022 3.1321 1.4037 +3.1859 3.1449 1.389 +3.3874 3.1883 1.3641 +3.559 3.2283 1.3454 +3.6877 3.2584 1.3314 +2.5342 2.9755 1.4086 +2.5382 3.0242 1.5019 +2.5592 3.0652 1.5964 +2.5943 3.1157 1.678 +2.6409 3.193 1.7329 +2.7067 3.1973 1.7104 +2.7589 3.1703 1.6564 +2.8073 3.1338 1.5904 +2.8627 3.1069 1.5307 +2.9365 3.1055 1.4944 +3.0203 3.1179 1.4725 +3.1035 3.1277 1.4481 +3.1873 3.1412 1.4278 +3.3884 3.1855 1.3931 +3.5598 3.2262 1.3672 +3.6883 3.2568 1.3477 +2.5542 2.8863 1.3496 +2.5438 2.94 1.4403 +2.5496 2.9781 1.548 +2.5715 3.0139 1.6594 +2.6093 3.0609 1.761 +2.663 3.1324 1.8396 +2.7287 3.1446 1.8138 +2.7743 3.1324 1.7508 +2.8148 3.1105 1.6721 +2.8649 3.0937 1.599 +2.9397 3.0968 1.553 +3.0232 3.1102 1.5251 +3.1058 3.121 1.4937 +3.1894 3.1353 1.4673 +3.39 3.1811 1.4228 +3.561 3.2229 1.3894 +3.6892 3.2543 1.3644 +2.5618 2.8709 1.3813 +2.5627 2.9071 1.4702 +2.5649 2.946 1.5724 +2.5881 2.9806 1.6725 +2.6264 3.0236 1.7663 +2.6807 3.0836 1.8476 +2.7446 3.0984 1.8298 +2.7894 3.0943 1.7862 +2.8285 3.0833 1.7309 +2.8756 3.0765 1.6776 +2.9444 3.0839 1.6392 +3.0278 3.0986 1.604 +3.1094 3.1109 1.5614 +3.1926 3.1266 1.5255 +3.3924 3.1746 1.4665 +3.5627 3.218 1.4221 +3.6905 3.2506 1.3889 +2.5786 2.9317 1.5585 +2.6077 2.9544 1.6447 +2.6491 2.9831 1.7263 +2.7012 3.0273 1.8005 +2.7619 3.0442 1.7962 +2.8074 3.0483 1.7845 +2.8476 3.0478 1.7677 +2.8927 3.0498 1.7467 +2.9528 3.0607 1.7222 +3.0361 3.0783 1.6794 +3.1156 3.0929 1.6266 +3.1983 3.1109 1.5815 +3.3966 3.1628 1.5085 +3.5659 3.2092 1.4536 +3.6929 3.244 1.4126 +2.569 2.8553 1.3734 +2.5765 2.8831 1.454 +2.5989 2.8992 1.5318 +2.6333 2.9119 1.6062 +2.6768 2.9288 1.6762 +2.7265 2.9579 1.7407 +2.7841 2.9766 1.7497 +2.8307 2.9881 1.7698 +2.8726 2.9967 1.7908 +2.9162 3.0061 1.8019 +2.9677 3.0199 1.7919 +3.0501 3.0423 1.7423 +3.1268 3.0613 1.6813 +3.2083 3.0834 1.6286 +3.4042 3.1422 1.5438 +3.5716 3.1938 1.4801 +3.6971 3.2324 1.4324 +2.5878 2.8057 1.3678 +2.6046 2.8122 1.4439 +2.6308 2.8225 1.517 +2.6656 2.8359 1.5862 +2.7084 2.8518 1.6509 +2.7586 2.8697 1.7104 +2.8149 2.8902 1.7274 +2.8621 2.9073 1.7664 +2.9044 2.9226 1.8098 +2.9461 2.9377 1.8396 +2.9916 2.9543 1.8382 +3.0719 2.9836 1.7839 +3.1453 3.0103 1.7175 +3.2244 3.0391 1.6598 +3.4162 3.109 1.5672 +3.5806 3.1688 1.4977 +3.7039 3.2137 1.4456 +2.6062 2.7531 1.3724 +2.63 2.7356 1.4525 +2.6574 2.7379 1.5303 +2.6916 2.7508 1.605 +2.736 2.7655 1.6754 +2.794 2.7724 1.7403 +2.85 2.7959 1.7492 +2.8923 2.8186 1.7691 +2.929 2.8409 1.7899 +2.9678 2.8633 1.8011 +3.0161 2.8868 1.7911 +3.0936 2.9228 1.7415 +3.1645 2.9579 1.6807 +3.241 2.9935 1.628 +3.4287 3.0748 1.5433 +3.59 3.1432 1.4798 +3.7109 3.1945 1.4322 +2.6105 2.7325 1.3764 +2.6338 2.6959 1.4712 +2.6636 2.6957 1.5573 +2.7002 2.6975 1.6443 +2.7507 2.7018 1.7268 +2.8209 2.6985 1.8026 +2.8782 2.7257 1.7978 +2.9145 2.7541 1.7852 +2.9434 2.783 1.7672 +2.9781 2.8128 1.7454 +3.0315 2.8447 1.7204 +3.1064 2.885 1.6778 +3.1766 2.9254 1.6252 +3.2514 2.9651 1.5803 +3.4364 3.0535 1.5075 +3.5958 3.1272 1.4529 +3.7153 3.1825 1.412 +2.6619 2.6756 1.5723 +2.7015 2.6643 1.6737 +2.759 2.6557 1.7689 +2.8415 2.6418 1.8514 +2.9003 2.6728 1.833 +2.9306 2.707 1.7878 +2.9515 2.7431 1.7305 +2.9818 2.7811 1.6754 +3.0399 2.8215 1.6361 +3.1131 2.8642 1.6012 +3.1833 2.9077 1.559 +3.2571 2.9495 1.5234 +3.4407 3.0418 1.4649 +3.599 3.1185 1.4209 +3.7177 3.1759 1.388 +2.6143 2.7204 1.3467 +2.6402 2.6723 1.4384 +2.6681 2.6476 1.5489 +2.7074 2.6346 1.663 +2.7676 2.6213 1.7655 +2.8581 2.5961 1.8409 +2.9169 2.6303 1.8146 +2.9426 2.671 1.7501 +2.9574 2.7162 1.6696 +2.9837 2.7635 1.595 +3.0437 2.8109 1.5483 +3.1162 2.8545 1.5209 +3.1865 2.8995 1.49 +3.2597 2.9424 1.4641 +3.4427 3.0364 1.4204 +3.6004 3.1144 1.3876 +3.7188 3.1729 1.363 +2.6208 2.7056 1.3294 +2.6545 2.6431 1.4055 +2.688 2.6099 1.4991 +2.7299 2.5928 1.594 +2.7896 2.5764 1.6747 +2.8768 2.5449 1.7259 +2.9304 2.5843 1.7038 +2.9524 2.6392 1.6504 +2.9652 2.699 1.5848 +2.9897 2.7559 1.5254 +3.0458 2.8051 1.4892 +3.1181 2.8493 1.4677 +3.1882 2.895 1.444 +3.2611 2.9384 1.4242 +3.4437 3.0335 1.3905 +3.6013 3.1122 1.3652 +3.7194 3.1713 1.3462 +2.6181 2.7179 1.3246 +2.6548 2.6596 1.3848 +2.6941 2.623 1.4554 +2.741 2.5983 1.523 +2.8005 2.5749 1.5742 +2.878 2.5417 1.5958 +2.927 2.5792 1.5803 +2.9525 2.6352 1.5428 +2.9707 2.6977 1.4969 +2.9972 2.7564 1.4555 +3.0468 2.8026 1.4314 +3.1188 2.8469 1.4163 +3.1892 2.8932 1.3993 +3.2617 2.9367 1.3852 +3.4442 3.0322 1.3612 +3.6016 3.1113 1.3432 +3.7197 3.1705 1.3298 +2.6094 2.7444 1.2847 +2.6437 2.6991 1.319 +2.6851 2.6637 1.3731 +2.7349 2.6343 1.4282 +2.7944 2.607 1.4652 +2.8648 2.5778 1.4652 +2.9127 2.6111 1.4567 +2.9429 2.6605 1.4363 +2.967 2.7168 1.411 +2.9966 2.7704 1.3882 +3.0433 2.8122 1.375 +3.1156 2.8555 1.366 +3.1866 2.9007 1.3557 +3.2594 2.9432 1.3472 +3.4424 3.037 1.3327 +3.6003 3.1149 1.3218 +3.7187 3.1733 1.3137 +2.6416 2.7035 1.2897 +2.6831 2.667 1.3173 +2.732 2.64 1.3479 +2.7879 2.6231 1.3704 +2.8506 2.6168 1.3734 +2.8974 2.6475 1.3693 +2.9305 2.6927 1.3593 +2.9588 2.744 1.3471 +2.9912 2.7928 1.3362 +3.0367 2.8304 1.33 +3.1096 2.8718 1.3256 +3.1815 2.9149 1.3208 +3.2549 2.9555 1.3168 +3.4391 3.0463 1.3099 +3.5978 3.1218 1.3047 +3.7168 3.1785 1.3009 +6.0092 1.496 0.5494 +6.0112 1.4948 0.5103 +6.0153 1.5184 0.5422 +5.9911 1.5418 0.5756 +5.9828 1.5112 0.5854 +5.7786 1.6291 0.8053 +5.7871 1.6655 0.7952 +5.6086 1.7744 1.0405 +5.5999 1.7322 1.0506 +5.5712 1.7488 1.0753 +5.5779 1.7821 1.0675 +5.5476 1.7892 1.095 +5.5429 1.7652 1.1003 +5.537 1.7686 1.1304 +5.5432 1.8007 1.1234 +5.542 1.813 1.1529 +5.5338 1.7704 1.162 +5.4697 1.8074 1.3217 +5.4805 1.8647 1.3095 +5.4033 1.9086 1.4626 +5.3927 1.8519 1.4745 +5.311 1.8991 1.624 +5.3206 1.9513 1.6133 +5.2915 1.9533 1.6321 +5.2843 1.9145 1.6401 +5.2577 1.9298 1.6564 +5.2625 1.9556 1.651 +5.2621 1.9702 1.6868 +5.2548 1.9315 1.695 +5.2519 1.9332 1.7336 +5.2617 1.9849 1.7225 +5.1325 2.0641 1.9569 +5.1214 2.0085 1.9696 +4.9826 2.0886 2.1992 +4.995 2.1479 2.1848 +4.9618 2.1506 2.2008 +4.9525 2.106 2.2116 +4.9222 2.1235 2.2239 +4.9284 2.1533 2.2166 +4.9298 2.1692 2.2473 +4.9191 2.1253 2.2599 +4.9144 2.128 2.293 +4.9298 2.1861 2.2748 +4.827 2.2481 2.3383 +4.805 2.1912 2.3611 +4.6729 2.2674 2.38 +4.7035 2.3231 2.354 +4.5721 2.4016 2.3288 +4.5325 2.3485 2.3549 +4.5182 2.3568 2.3258 +4.5483 2.3965 2.3063 +4.5247 2.3911 2.2827 +4.5042 2.3649 2.2955 +4.476 2.3812 2.299 +4.5033 2.4134 2.2837 +4.4867 2.4415 2.2936 +4.4476 2.3975 2.3137 +4.4227 2.4119 2.3125 +4.4688 2.4619 2.2905 +4.3572 2.5284 2.1709 +4.3101 2.4769 2.1921 +4.215 2.5318 2.0443 +4.2644 2.5852 2.0233 +4.1812 2.6371 1.859 +4.1286 2.5817 1.8803 +4.0424 2.6315 1.7115 +4.0984 2.6887 1.6894 +4.0068 2.7447 1.5259 +3.9477 2.6861 1.549 +3.8358 2.7508 1.4041 +3.8973 2.81 1.38 +3.8721 2.8125 1.3446 +3.819 2.7604 1.3664 +3.8103 2.7655 1.322 +3.848 2.8036 1.3053 +3.8203 2.8074 1.2729 +3.7912 2.7765 1.2868 +3.7761 2.7852 1.2927 +3.8111 2.8249 1.2742 +3.8069 2.8503 1.2878 +3.7611 2.7939 1.3149 +3.7453 2.803 1.3228 +3.7962 2.8687 1.2912 +3.6962 2.9265 1.2748 +3.6489 2.8587 1.305 +3.5366 2.9235 1.3325 +3.5808 2.9931 1.3013 +3.4592 3.0634 1.3428 +3.4178 2.9921 1.3758 +3.3017 3.0591 1.4055 +3.3404 3.132 1.3715 +3.293 3.0641 1.2905 +6.0077 1.5336 0.5247 +5.9805 1.5625 0.552 +5.7717 1.6915 0.7708 +5.5886 1.8055 1.0161 +5.5619 1.8067 1.0488 +5.5357 1.8072 1.082 +5.5272 1.8248 1.1064 +5.5206 1.8449 1.1307 +5.4516 1.9078 1.2803 +5.3744 1.9514 1.4342 +5.2938 1.9906 1.5876 +5.2716 1.9826 1.6128 +5.2494 1.975 1.638 +5.2426 1.9993 1.667 +5.2356 2.0237 1.6959 +5.1056 2.1053 1.9263 +4.9672 2.1915 2.1501 +4.941 2.1833 2.1746 +4.9146 2.1751 2.199 +4.9125 2.1999 2.2162 +4.909 2.2258 2.2309 +4.8208 2.2805 2.2825 +4.7147 2.3471 2.2909 +4.6018 2.4159 2.2658 +4.5714 2.4068 2.2591 +4.5412 2.3973 2.2516 +4.5286 2.4188 2.247 +4.5243 2.4475 2.2451 +4.5142 2.4676 2.237 +4.4036 2.5345 2.1197 +4.3136 2.5911 1.9723 +4.2345 2.6421 1.8069 +4.1563 2.6925 1.6354 +4.0694 2.7471 1.4697 +3.9639 2.8109 1.3218 +3.9289 2.814 1.2919 +3.8877 2.8056 1.2654 +3.8493 2.8103 1.2391 +3.8424 2.8318 1.2278 +3.8455 2.8624 1.2214 +3.837 2.8847 1.2145 +3.7286 2.9473 1.2011 +3.6059 3.0182 1.2254 +3.4773 3.0924 1.2631 +3.3512 3.1652 1.2893 +5.9907 1.5326 0.5073 +5.9573 1.5613 0.5283 +5.7416 1.6918 0.7465 +5.5517 1.8073 0.9917 +5.5326 1.8082 1.03 +5.5143 1.8085 1.0691 +5.4983 1.8266 1.0895 +5.4823 1.8475 1.1086 +5.3999 1.9113 1.251 +5.323 1.955 1.4057 +5.2463 1.9941 1.5619 +5.2363 1.9852 1.5936 +5.226 1.9767 1.625 +5.2076 2.0017 1.6472 +5.189 2.0269 1.6693 +5.0563 2.1081 1.8955 +4.9156 2.1938 2.1153 +4.9022 2.185 2.1484 +4.8888 2.1761 2.1814 +4.8773 2.1995 2.1852 +4.8643 2.2239 2.1872 +4.7897 2.2696 2.2272 +4.6997 2.3254 2.2283 +4.6043 2.383 2.2029 +4.574 2.3816 2.212 +4.5441 2.3799 2.2206 +4.5368 2.3941 2.2102 +4.5378 2.4119 2.1963 +4.532 2.4254 2.1834 +4.4213 2.4914 2.0688 +4.3327 2.5459 1.9221 +4.256 2.594 1.7558 +4.181 2.641 1.5825 +4.0977 2.6922 1.4144 +3.996 2.753 1.2642 +3.9559 2.7641 1.2395 +3.9057 2.7703 1.2255 +3.8612 2.7837 1.2053 +3.852 2.8013 1.1818 +3.854 2.823 1.1558 +3.8433 2.8415 1.1388 +3.7274 2.9084 1.1261 +3.5973 2.9836 1.1484 +3.4613 3.0622 1.1829 +3.3279 3.1392 1.2071 +5.9743 1.5161 0.5 +5.935 1.5388 0.5185 +5.7143 1.6662 0.7364 +5.5195 1.7787 0.9816 +5.5072 1.7858 1.0223 +5.4958 1.7924 1.0638 +5.4736 1.8052 1.0825 +5.4495 1.8191 1.0994 +5.3557 1.8732 1.2389 +5.2792 1.9174 1.3939 +5.206 1.9597 1.5513 +5.2063 1.9595 1.5856 +5.2061 1.9596 1.6196 +5.1777 1.976 1.639 +5.1491 1.9925 1.6582 +5.0137 2.0707 1.8828 +4.8704 2.1535 2.1009 +4.8683 2.1547 2.1375 +4.8662 2.1559 2.1741 +4.8446 2.1683 2.1727 +4.8218 2.1815 2.1691 +4.7515 2.2221 2.2046 +4.6668 2.271 2.2025 +4.5781 2.3222 2.1768 +4.5547 2.3357 2.1925 +4.5316 2.349 2.2077 +4.5227 2.3541 2.195 +4.5192 2.3562 2.176 +4.5118 2.3605 2.1613 +4.4 2.425 2.048 +4.3107 2.4765 1.9017 +4.2338 2.521 1.7351 +4.159 2.5642 1.5609 +4.0762 2.612 1.3918 +3.9752 2.6703 1.2404 +3.9372 2.6922 1.2178 +3.8915 2.7186 1.2089 +3.8491 2.7431 1.1913 +3.8351 2.7512 1.1634 +3.8279 2.7553 1.1291 +3.8118 2.7646 1.1076 +3.6929 2.8332 1.0954 +3.5597 2.9102 1.1166 +3.4205 2.9905 1.1497 +3.2841 3.0693 1.1731 +5.9682 1.4936 0.5073 +5.9267 1.5082 0.5283 +5.7058 1.6298 0.7465 +5.5109 1.7365 0.9917 +5.5005 1.7525 1.03 +5.4911 1.7683 1.0691 +5.4674 1.773 1.0895 +5.4413 1.7765 1.1086 +5.3448 1.8159 1.251 +5.2685 1.8607 1.4057 +5.1963 1.9075 1.5619 +5.1991 1.9207 1.5936 +5.2013 1.9338 1.625 +5.1704 1.9373 1.6472 +5.1393 1.9408 1.6693 +5.0027 2.0151 1.8955 +4.858 2.0941 2.1153 +4.859 2.1101 2.1484 +4.8599 2.1261 2.1814 +4.834 2.1244 2.1852 +4.8064 2.1235 2.1872 +4.7294 2.1653 2.2272 +4.6361 2.2153 2.2283 +4.5385 2.2691 2.2029 +4.5246 2.296 2.212 +4.5111 2.3228 2.2206 +4.4952 2.322 2.2102 +4.4802 2.3122 2.1963 +4.4657 2.3106 2.1834 +4.3531 2.3733 2.0688 +4.2617 2.4229 1.9221 +4.1817 2.4653 1.7558 +4.1035 2.5067 1.5825 +4.0175 2.5532 1.4144 +3.914 2.611 1.2642 +3.8843 2.6401 1.2395 +3.8538 2.6805 1.2255 +3.82 2.7123 1.2053 +3.8001 2.7115 1.1818 +3.7824 2.6989 1.1558 +3.761 2.6989 1.1388 +3.6451 2.7658 1.1261 +3.5149 2.8409 1.1484 +3.3789 2.9194 1.1829 +3.2454 2.9964 1.2071 +5.9759 1.4785 0.5247 +5.9372 1.4875 0.552 +5.7212 1.6038 0.7708 +5.5308 1.7054 1.0161 +5.5165 1.728 1.0488 +5.5029 1.7504 1.082 +5.4834 1.749 1.1064 +5.4627 1.7446 1.1307 +5.3737 1.7729 1.2803 +5.2974 1.818 1.4342 +5.2231 1.8682 1.5876 +5.2189 1.8914 1.6128 +5.2144 1.9144 1.638 +5.19 1.9082 1.667 +5.1653 1.902 1.6959 +5.0297 1.9738 1.9263 +4.8858 2.0506 2.1501 +4.8798 2.0774 2.1746 +4.8738 2.1044 2.199 +4.8512 2.0937 2.2162 +4.827 2.0838 2.2309 +4.7355 2.1329 2.2825 +4.6249 2.1914 2.2909 +4.5088 2.2548 2.2658 +4.5015 2.2857 2.2591 +4.4946 2.3165 2.2516 +4.4697 2.3168 2.247 +4.4427 2.3062 2.2451 +4.4202 2.3049 2.237 +4.3069 2.3672 2.1197 +4.213 2.4168 1.9723 +4.1292 2.4598 1.8069 +4.0465 2.5023 1.6354 +3.9557 2.5503 1.4697 +3.8478 2.6098 1.3218 +3.8276 2.6385 1.2919 +3.8143 2.6784 1.2654 +3.791 2.7093 1.2391 +3.7689 2.7046 1.2278 +3.744 2.6865 1.2214 +3.7204 2.6827 1.2145 +3.612 2.7453 1.2011 +3.4893 2.8162 1.2254 +3.3606 2.8904 1.2631 +3.2346 2.9632 1.2893 +5.9928 1.4794 0.5422 +5.9604 1.4887 0.5756 +5.7513 1.6035 0.7952 +5.5677 1.7036 1.0405 +5.5457 1.7264 1.0675 +5.5244 1.7491 1.095 +5.5123 1.7471 1.1234 +5.501 1.7421 1.1529 +5.4255 1.7694 1.3095 +5.3489 1.8143 1.4626 +5.2706 1.8647 1.6133 +5.2542 1.8888 1.6321 +5.2378 1.9128 1.651 +5.2249 1.9058 1.6868 +5.212 1.8988 1.7225 +5.0788 1.9711 1.9569 +4.9374 2.0483 2.1848 +4.9185 2.0757 2.2008 +4.8995 2.1033 2.2166 +4.8864 2.0941 2.2473 +4.8718 2.0857 2.2748 +4.7667 2.1437 2.3383 +4.64 2.2131 2.354 +4.5063 2.2877 2.3288 +4.4989 2.3108 2.3063 +4.4917 2.334 2.2827 +4.4617 2.3414 2.2837 +4.4291 2.3417 2.2936 +4.4025 2.347 2.2905 +4.289 2.4104 2.1709 +4.1934 2.4623 2.0233 +4.107 2.5084 1.859 +4.0209 2.5544 1.6894 +3.9265 2.6056 1.5259 +3.8152 2.6679 1.38 +3.8005 2.6885 1.3446 +3.7962 2.7137 1.3053 +3.779 2.7359 1.2729 +3.7592 2.735 1.2742 +3.7352 2.7261 1.2878 +3.7138 2.726 1.2912 +3.6138 2.7838 1.2748 +3.4984 2.8504 1.3013 +3.3768 2.9205 1.3428 +3.2579 2.9892 1.3715 +4.7043 0.6195 0.5494 +4.7054 0.6177 0.5103 +4.7211 0.6353 0.5422 +4.7134 0.6648 0.5757 +4.6906 0.6433 0.5854 +4.5845 0.8271 0.8053 +4.6105 0.8532 0.7953 +4.5208 1.0187 1.0407 +4.4917 0.9879 1.0506 +4.4767 1.0138 1.0753 +4.4996 1.038 1.0676 +4.4785 1.0568 1.0951 +4.462 1.0392 1.1003 +4.459 1.0445 1.1304 +4.4809 1.0681 1.1235 +4.4863 1.0787 1.153 +4.4573 1.0474 1.162 +4.424 1.1051 1.3217 +4.4629 1.1472 1.3097 +4.4224 1.2162 1.4628 +4.384 1.1743 1.4745 +4.3415 1.2479 1.624 +4.3767 1.2864 1.6135 +4.3538 1.3006 1.6322 +4.3276 1.272 1.6401 +4.3138 1.2959 1.6564 +4.3313 1.3149 1.6511 +4.3386 1.3269 1.6869 +4.3123 1.2985 1.695 +4.3108 1.3011 1.7336 +4.3459 1.3391 1.7227 +4.2812 1.4592 1.9571 +4.243 1.4185 1.9696 +4.1709 1.5434 2.1992 +4.2121 1.5866 2.185 +4.1862 1.603 2.2009 +4.1553 1.5706 2.2116 +4.1395 1.5979 2.2239 +4.1602 1.6195 2.2167 +4.1696 1.632 2.2475 +4.1379 1.6006 2.2599 +4.1354 1.6049 2.293 +4.1785 1.6459 2.275 +4.1265 1.7406 2.3385 +4.0786 1.7033 2.3611 +4.01 1.8222 2.38 +4.0643 1.8549 2.3541 +3.9974 1.9754 2.3289 +3.937 1.9485 2.3549 +3.9296 1.9615 2.3258 +3.9752 1.9813 2.3063 +3.9529 1.9869 2.2827 +3.9223 1.974 2.2955 +3.9076 1.9994 2.299 +3.947 2.0143 2.2838 +3.9479 2.0445 2.2937 +3.8929 2.025 2.3137 +3.8799 2.0474 2.3125 +3.9439 2.0689 2.2907 +3.887 2.1711 2.1711 +3.8214 2.1487 2.1921 +3.772 2.2343 2.0443 +3.8405 2.2572 2.0235 +3.7992 2.3352 1.8592 +3.7272 2.312 1.8803 +3.6824 2.3896 1.7115 +3.7581 2.4129 1.6896 +3.7122 2.498 1.5262 +3.6331 2.4749 1.549 +3.575 2.5756 1.4041 +3.6563 2.5982 1.3803 +3.6369 2.611 1.3448 +3.5663 2.5907 1.3664 +3.5617 2.5985 1.322 +3.6126 2.6139 1.3055 +3.5918 2.6288 1.2729 +3.5518 2.6158 1.2868 +3.544 2.6293 1.2927 +3.5935 2.6471 1.2743 +3.6034 2.6697 1.2879 +3.5362 2.6429 1.3149 +3.528 2.6571 1.3228 +3.6043 2.6894 1.2912 +3.5523 2.7795 1.2749 +3.4779 2.7438 1.305 +3.4195 2.8449 1.3325 +3.4924 2.8834 1.3014 +3.4293 2.9928 1.3429 +3.3578 2.9518 1.3758 +3.2975 3.0563 1.4055 +3.3676 3.0998 1.3715 +3.2929 3.0641 1.2905 +4.7228 0.6511 0.5247 +4.7157 0.6865 0.552 +4.6116 0.8813 0.7708 +4.5208 1.053 1.0161 +4.4995 1.0653 1.0488 +4.4782 1.0768 1.082 +4.4804 1.0949 1.1064 +4.4856 1.1143 1.1307 +4.4618 1.1954 1.2803 +4.4212 1.264 1.4342 +4.3755 1.3306 1.5876 +4.353 1.3334 1.6128 +4.3307 1.3366 1.638 +4.3378 1.3594 1.667 +4.345 1.3825 1.6959 +4.2808 1.5049 1.9263 +4.2122 1.6346 2.1501 +4.1864 1.639 2.1746 +4.1603 1.6435 2.199 +4.1716 1.6648 2.2162 +4.1823 1.6876 2.2309 +4.1385 1.7701 2.2825 +4.0862 1.8699 2.2909 +4.0294 1.9745 2.2658 +3.9996 1.98 2.2591 +3.9698 1.985 2.2516 +3.9707 2.008 2.247 +3.9822 2.0335 2.2451 +3.9844 2.0543 2.237 +3.9286 2.1564 2.1197 +3.8843 2.2412 1.9723 +3.8459 2.3168 1.8069 +3.8081 2.3914 1.6354 +3.7653 2.4733 1.4697 +3.712 2.5706 1.3218 +3.6848 2.588 1.2919 +3.6464 2.5986 1.2654 +3.6174 2.6189 1.2391 +3.6229 2.6394 1.2278 +3.6416 2.6633 1.2214 +3.6464 2.6853 1.2145 +3.59 2.7829 1.2011 +3.5262 2.8933 1.2254 +3.4594 3.0091 1.2631 +3.3939 3.1225 1.2893 +4.7082 0.6576 0.5072 +4.6958 0.6953 0.5282 +4.5868 0.8944 0.7464 +4.4911 1.0701 0.9916 +4.4759 1.079 1.0299 +4.461 1.087 1.069 +4.4574 1.1088 1.0894 +4.4551 1.1327 1.1084 +4.4207 1.2203 1.2508 +4.3804 1.2889 1.4055 +4.3378 1.3537 1.5618 +4.325 1.3506 1.5934 +4.3122 1.3479 1.6249 +4.3101 1.3763 1.6471 +4.3079 1.405 1.6691 +4.2414 1.5282 1.8954 +4.1706 1.6585 2.1151 +4.1551 1.6569 2.1482 +4.1395 1.6553 2.1813 +4.1422 1.6794 2.1851 +4.1443 1.705 2.187 +4.107 1.7743 2.227 +4.0623 1.8585 2.2282 +4.0142 1.9464 2.2028 +3.9885 1.9581 2.2119 +3.963 1.9694 2.2206 +3.9644 1.9842 2.2102 +3.9746 1.9984 2.1962 +3.9768 2.0119 2.1832 +3.9205 2.1132 2.0686 +3.8761 2.1956 1.9219 +3.8382 2.2678 1.7556 +3.8012 2.3383 1.5823 +3.7596 2.4158 1.4142 +3.7077 2.509 1.2639 +3.6806 2.5352 1.2393 +3.6426 2.5618 1.2254 +3.6131 2.5918 1.2052 +3.6148 2.6103 1.1817 +3.6278 2.6272 1.1557 +3.6287 2.647 1.1387 +3.5685 2.7513 1.1261 +3.501 2.8684 1.1483 +3.4304 2.9909 1.1829 +3.3611 3.111 1.2071 +4.6862 0.6509 0.5 +4.6658 0.6863 0.5185 +4.5511 0.8849 0.7364 +4.4499 1.0602 0.9816 +4.4435 1.0713 1.0223 +4.4375 1.0816 1.0638 +4.426 1.1016 1.0825 +4.4135 1.1233 1.0994 +4.3648 1.2077 1.2389 +4.325 1.2766 1.3939 +4.287 1.3424 1.5513 +4.2871 1.3422 1.5856 +4.287 1.3423 1.6196 +4.2723 1.3678 1.639 +4.2574 1.3937 1.6582 +4.1871 1.5155 1.8828 +4.1126 1.6445 2.1009 +4.1115 1.6464 2.1375 +4.1104 1.6483 2.1741 +4.0992 1.6676 2.1727 +4.0873 1.6882 2.1691 +4.0508 1.7514 2.2046 +4.0068 1.8277 2.2025 +3.9607 1.9076 2.1768 +3.9486 1.9286 2.1925 +3.9366 1.9494 2.2077 +3.9319 1.9573 2.195 +3.9301 1.9605 2.176 +3.9263 1.9672 2.1613 +3.8682 2.0678 2.048 +3.8218 2.1481 1.9017 +3.7818 2.2174 1.7351 +3.7429 2.2847 1.5609 +3.6999 2.3592 1.3918 +3.6474 2.4501 1.2404 +3.6277 2.4843 1.2178 +3.6039 2.5255 1.2089 +3.5819 2.5636 1.1913 +3.5746 2.5762 1.1634 +3.5709 2.5827 1.1291 +3.5625 2.5972 1.1076 +3.5008 2.7042 1.0954 +3.4315 2.8241 1.1166 +3.3592 2.9493 1.1497 +3.2883 3.0721 1.1731 +4.6694 0.6352 0.5072 +4.6429 0.6648 0.5282 +4.5251 0.8588 0.7464 +4.4207 1.0295 0.9916 +4.4206 1.0471 1.0299 +4.4211 1.064 1.069 +4.4041 1.078 1.0894 +4.3845 1.092 1.1084 +4.3259 1.1656 1.2508 +4.2866 1.2348 1.4055 +4.2518 1.304 1.5618 +4.2609 1.3136 1.5934 +4.2696 1.3233 1.6249 +4.2461 1.3394 1.6471 +4.2223 1.3556 1.6691 +4.1489 1.4748 1.8954 +4.0714 1.6013 2.1151 +4.0805 1.6139 2.1482 +4.0897 1.6266 2.1813 +4.0675 1.6362 2.1851 +4.0443 1.6473 2.187 +4.0029 1.7143 2.227 +3.9524 1.795 2.2282 +3.9003 1.8807 2.2028 +3.903 1.9087 2.2119 +3.9059 1.9365 2.2206 +3.8925 1.9427 2.2102 +3.8751 1.9409 2.1962 +3.8623 1.9457 2.1832 +3.8027 2.0452 2.0686 +3.7535 2.1248 1.9219 +3.71 2.1937 1.7556 +3.6674 2.261 1.5823 +3.6211 2.3358 1.4142 +3.5663 2.4273 1.2639 +3.5572 2.4639 1.2393 +3.5531 2.5101 1.2254 +3.5419 2.5506 1.2052 +3.5251 2.5585 1.1817 +3.5039 2.5557 1.1557 +3.4863 2.5648 1.1387 +3.4261 2.669 1.1261 +3.3584 2.7861 1.1483 +3.2876 2.9085 1.1829 +3.2182 3.0286 1.2071 +4.6677 0.6193 0.5247 +4.6406 0.6431 0.552 +4.524 0.8307 0.7708 +4.4207 0.9952 1.0161 +4.4207 1.0198 1.0488 +4.4214 1.044 1.082 +4.4046 1.0512 1.1064 +4.3852 1.0564 1.1307 +4.3269 1.1175 1.2803 +4.2877 1.187 1.4342 +4.253 1.2599 1.5876 +4.2618 1.2808 1.6128 +4.2701 1.3016 1.638 +4.2468 1.3069 1.667 +4.2232 1.3122 1.6959 +4.1493 1.429 1.9263 +4.0713 1.5533 2.1501 +4.0804 1.5779 2.1746 +4.0896 1.6026 2.199 +4.0655 1.6035 2.2162 +4.0404 1.6056 2.2309 +3.9908 1.6849 2.2825 +3.9305 1.78 2.2909 +3.8683 1.8815 2.2658 +3.8785 1.91 2.2591 +3.889 1.9384 2.2516 +3.8687 1.9492 2.247 +3.8409 1.9519 2.2451 +3.8217 1.9604 2.237 +3.7612 2.0598 2.1197 +3.71 2.1405 1.9723 +3.6637 2.2115 1.8069 +3.6179 2.2816 1.6354 +3.5684 2.3597 1.4697 +3.5108 2.4545 1.3218 +3.5094 2.4867 1.2919 +3.5193 2.5252 1.2654 +3.5163 2.5605 1.2391 +3.4957 2.566 1.2278 +3.4658 2.5618 1.2214 +3.4443 2.5686 1.2145 +3.388 2.6662 1.2011 +3.3242 2.7767 1.2254 +3.2574 2.8924 1.2631 +3.1919 3.0059 1.2893 +4.6823 0.6129 0.5422 +4.6605 0.6343 0.5757 +4.5488 0.8176 0.7953 +4.4504 0.978 1.0407 +4.4443 1.0061 1.0676 +4.4385 1.0338 1.0951 +4.4276 1.0373 1.1235 +4.4157 1.038 1.153 +4.3681 1.0925 1.3097 +4.3286 1.162 1.4628 +4.2906 1.2367 1.6135 +4.2898 1.2636 1.6322 +4.2887 1.2903 1.6511 +4.2746 1.29 1.6869 +4.2603 1.2897 1.7227 +4.1888 1.4058 1.9571 +4.1129 1.5294 2.185 +4.1117 1.56 2.2009 +4.1104 1.5908 2.2167 +4.0949 1.5888 2.2475 +4.0784 1.5881 2.275 +4.0223 1.6805 2.3385 +3.9545 1.7915 2.3541 +3.8836 1.9097 2.3289 +3.8896 1.9319 2.3063 +3.8958 1.9539 2.2827 +3.8751 1.9728 2.2838 +3.8485 1.9871 2.2937 +3.8294 2.0028 2.2907 +3.7693 2.1031 2.1711 +3.7179 2.1865 2.0235 +3.671 2.2612 1.8592 +3.6243 2.3356 1.6896 +3.5736 2.418 1.5262 +3.5147 2.5165 1.3803 +3.5134 2.5397 1.3448 +3.5231 2.5621 1.3055 +3.5206 2.5876 1.2729 +3.5038 2.5953 1.2743 +3.4793 2.5981 1.2879 +3.4617 2.6072 1.2912 +3.4098 2.6972 1.2749 +3.3497 2.801 1.3014 +3.2865 2.9104 1.3429 +3.2247 3.0174 1.3715 +3.0469 0.2521 0.5494 +3.0467 0.25 0.5103 +3.0696 0.2554 0.5422 +3.0803 0.284 0.5757 +3.0493 0.2795 0.5854 +3.0678 0.4908 0.8053 +3.1041 0.4973 0.7953 +3.1255 0.6843 1.0407 +3.0839 0.6758 1.0506 +3.0865 0.7056 1.0753 +3.1192 0.7123 1.0676 +3.1127 0.7398 1.0951 +3.0891 0.7348 1.1003 +3.0896 0.7409 1.1304 +3.1211 0.7477 1.1235 +3.1316 0.7533 1.153 +3.0899 0.7442 1.162 +3.0957 0.8106 1.3217 +3.1517 0.8228 1.3097 +3.1581 0.9025 1.4628 +3.1027 0.8903 1.4745 +3.1101 0.975 1.624 +3.161 0.9863 1.6135 +3.1504 1.011 1.6322 +3.1125 1.0026 1.6401 +3.1149 1.0301 1.6564 +3.1401 1.0357 1.6511 +3.153 1.0414 1.6869 +3.1152 1.0331 1.695 +3.1155 1.0361 1.7336 +3.166 1.0471 1.7227 +3.1818 1.1826 1.9571 +3.1273 1.1711 1.9696 +3.1399 1.3149 2.1992 +3.1983 1.3266 2.185 +3.1865 1.3549 2.2009 +3.1426 1.346 2.2116 +3.1453 1.3775 2.2239 +3.1747 1.3833 2.2167 +3.1896 1.3881 2.2475 +3.1456 1.3806 2.2599 +3.146 1.3855 2.293 +3.2048 1.3944 2.275 +3.2166 1.5019 2.3385 +3.1559 1.4988 2.3611 +3.1679 1.6355 2.38 +3.2312 1.6311 2.3541 +3.2455 1.7682 2.3289 +3.1806 1.7808 2.3549 +3.1819 1.7957 2.3258 +3.2307 1.7858 2.3063 +3.2157 1.8031 2.2827 +3.1832 1.8102 2.2955 +3.1857 1.8394 2.299 +3.2265 1.829 2.2838 +3.2446 1.8532 2.2937 +3.1883 1.8688 2.3137 +3.1906 1.8946 2.3125 +3.2553 1.8755 2.2907 +3.2673 1.9918 2.1711 +3.2008 2.0111 2.1921 +3.2094 2.1096 2.0443 +3.2786 2.0891 2.0235 +3.2895 2.1767 1.8592 +3.2172 2.199 1.8803 +3.225 2.2882 1.7115 +3.3004 2.2638 1.6896 +3.3116 2.3599 1.5262 +3.2336 2.3863 1.549 +3.2437 2.5022 1.4041 +3.3233 2.4741 1.3803 +3.3147 2.4956 1.3448 +3.2452 2.5195 1.3664 +3.246 2.5286 1.322 +3.2965 2.5119 1.3055 +3.288 2.5361 1.2729 +3.2478 2.5484 1.2868 +3.2491 2.564 1.2927 +3.2999 2.5501 1.2743 +3.3209 2.563 1.2879 +3.2505 2.5795 1.3149 +3.2519 2.5959 1.3228 +3.333 2.5786 1.2912 +3.3421 2.6822 1.2749 +3.2607 2.6957 1.305 +3.2708 2.8119 1.3325 +3.3526 2.8016 1.3014 +3.3637 2.9275 1.3429 +3.2816 2.9349 1.3758 +3.2921 3.0551 1.4055 +3.3745 3.0506 1.3715 +3.0801 0.2673 0.5247 +3.0946 0.3004 0.552 +3.1211 0.5197 0.7708 +3.1452 0.7124 1.0161 +3.1347 0.7347 1.0488 +3.1239 0.7564 1.082 +3.1361 0.7699 1.1064 +3.1515 0.7828 1.1307 +3.1785 0.8629 1.2803 +3.1846 0.9424 1.4342 +3.1853 1.0232 1.5876 +3.1685 1.0384 1.6128 +3.1521 1.0537 1.638 +3.1711 1.0684 1.667 +3.1902 1.0832 1.6959 +3.2078 1.2203 1.9263 +3.226 1.3659 2.1501 +3.2073 1.3843 2.1746 +3.1885 1.4029 2.199 +3.21 1.4138 2.2162 +3.2319 1.4264 2.2309 +3.2433 1.5192 2.2825 +3.2577 1.6309 2.2909 +3.2712 1.7491 2.2658 +3.2499 1.7707 2.2591 +3.2284 1.7919 2.2516 +3.2423 1.8103 2.247 +3.2663 1.8245 2.2451 +3.2801 1.8403 2.237 +3.2929 1.9559 2.1197 +3.3052 2.0508 1.9723 +3.3172 2.1347 1.8069 +3.3291 2.2176 1.6354 +3.3409 2.3092 1.4697 +3.3531 2.4195 1.3218 +3.3408 2.4493 1.2919 +3.3155 2.48 1.2654 +3.3032 2.5133 1.2391 +3.3196 2.5269 1.2278 +3.3486 2.5358 1.2214 +3.3651 2.5511 1.2145 +3.3749 2.6633 1.2011 +3.386 2.7904 1.2254 +3.3977 2.9235 1.2631 +3.4091 3.054 1.2893 +3.0719 0.281 0.5072 +3.0834 0.3191 0.5282 +3.1082 0.5447 0.7464 +3.1307 0.7435 0.9916 +3.1233 0.7595 1.0299 +3.1157 0.7746 1.069 +3.1252 0.7945 1.0894 +3.137 0.8154 1.1084 +3.1591 0.9069 1.2508 +3.1654 0.9862 1.4055 +3.1677 1.0637 1.5618 +3.1554 1.0685 1.5934 +3.1434 1.0736 1.6249 +3.158 1.0981 1.6471 +3.1727 1.1229 1.6691 +3.1888 1.2619 1.8954 +3.2056 1.4093 2.1151 +3.192 1.4169 2.1482 +3.1783 1.4246 2.1813 +3.1944 1.4427 2.1851 +3.2107 1.4625 2.187 +3.2199 1.5407 2.227 +3.2316 1.6352 2.2282 +3.2426 1.7349 2.2028 +3.2283 1.7592 2.2119 +3.2139 1.7831 2.2206 +3.2235 1.7944 2.2102 +3.24 1.8001 2.1962 +3.2495 1.8099 2.1832 +3.2615 1.9252 2.0686 +3.2725 2.0182 1.9219 +3.2828 2.099 1.7556 +3.2929 2.178 1.5823 +3.3033 2.2654 1.4142 +3.3143 2.3714 1.2639 +3.3071 2.4085 1.2393 +3.2912 2.4521 1.2254 +3.2843 2.4935 1.2052 +3.2962 2.5077 1.1817 +3.3166 2.5141 1.1557 +3.3287 2.5298 1.1387 +3.3392 2.6498 1.1261 +3.3511 2.7845 1.1483 +3.3635 2.9253 1.1829 +3.3756 3.0635 1.2071 +3.05 0.2882 0.5 +3.0536 0.3289 0.5185 +3.0736 0.5574 0.7364 +3.0912 0.759 0.9816 +3.0923 0.7718 1.0223 +3.0934 0.7836 1.0638 +3.0954 0.8066 1.0825 +3.0976 0.8316 1.0994 +3.1061 0.9286 1.2389 +3.113 1.0079 1.3939 +3.1196 1.0837 1.5513 +3.1196 1.0833 1.5856 +3.1196 1.0835 1.6196 +3.1222 1.1129 1.639 +3.1248 1.1426 1.6582 +3.137 1.2827 1.8828 +3.15 1.4311 2.1009 +3.1502 1.4333 2.1375 +3.1504 1.4354 2.1741 +3.1524 1.4577 2.1727 +3.1544 1.4814 2.1691 +3.1608 1.5541 2.2046 +3.1685 1.6418 2.2025 +3.1765 1.7337 2.1768 +3.1786 1.7579 2.1925 +3.1807 1.7818 2.2077 +3.1815 1.791 2.195 +3.1818 1.7946 2.176 +3.1825 1.8023 2.1613 +3.1926 1.918 2.048 +3.2007 2.0104 1.9017 +3.2077 2.0901 1.7351 +3.2145 2.1676 1.5609 +3.222 2.2533 1.3918 +3.2311 2.3578 1.2404 +3.2345 2.3971 1.2178 +3.2387 2.4445 1.2089 +3.2425 2.4884 1.1913 +3.2438 2.5029 1.1634 +3.2444 2.5103 1.1291 +3.2459 2.527 1.1076 +3.2567 2.6501 1.0954 +3.2687 2.788 1.1166 +3.2813 2.9321 1.1497 +3.2937 3.0733 1.1731 +3.0273 0.2849 0.5072 +3.0225 0.3244 0.5282 +3.0373 0.5509 0.7464 +3.0497 0.7506 0.9916 +3.0597 0.765 1.0299 +3.0698 0.7786 1.069 +3.0639 0.7998 1.0894 +3.0559 0.8225 1.1084 +3.0501 0.9164 1.2508 +3.0576 0.9957 1.4055 +3.0688 1.0723 1.5618 +3.0817 1.0749 1.5934 +3.0944 1.0779 1.6249 +3.0844 1.1046 1.6471 +3.0742 1.1315 1.6691 +3.0825 1.2712 1.8954 +3.0915 1.4193 2.1151 +3.1062 1.4244 2.1482 +3.1211 1.4296 2.1813 +3.1084 1.4502 2.1851 +3.0957 1.4725 2.187 +3.1002 1.5511 2.227 +3.1051 1.6462 2.2282 +3.1116 1.7463 2.2028 +3.1299 1.7678 2.2119 +3.1482 1.7888 2.2206 +3.1408 1.8016 2.2102 +3.1255 1.8101 2.1962 +3.1178 1.8214 2.1832 +3.126 1.9371 2.0686 +3.1314 2.0305 1.9219 +3.1353 2.1119 1.7556 +3.139 2.1915 1.5823 +3.144 2.2793 1.4142 +3.1516 2.3857 1.2639 +3.1651 2.4209 1.2393 +3.1882 2.4611 1.2254 +3.2023 2.5007 1.2052 +3.193 2.5168 1.1817 +3.174 2.5266 1.1557 +3.1649 2.5441 1.1387 +3.1753 2.6641 1.1261 +3.187 2.7988 1.1483 +3.1993 2.9397 1.1829 +3.2113 3.0778 1.2071 +3.0168 0.2729 0.5247 +3.0082 0.308 0.552 +3.0203 0.5285 0.7708 +3.03 0.7225 1.0161 +3.0442 0.7426 1.0488 +3.0586 0.7621 1.082 +3.0489 0.7776 1.1064 +3.036 0.7929 1.1307 +3.0233 0.8765 1.2803 +3.0311 0.9559 1.4342 +3.0444 1.0355 1.5876 +3.0636 1.0476 1.6128 +3.0824 1.0598 1.638 +3.0663 1.0776 1.667 +3.0501 1.0954 1.6959 +3.0565 1.2335 1.9263 +3.0639 1.38 2.1501 +3.0855 1.395 2.1746 +3.1072 1.41 2.199 +3.0879 1.4245 2.2162 +3.0686 1.4407 2.2309 +3.0734 1.534 2.2825 +3.0787 1.6465 2.2909 +3.0859 1.7654 2.2658 +3.1106 1.7829 2.2591 +3.1355 1.8 2.2516 +3.125 1.8206 2.247 +3.1038 1.8387 2.2451 +3.0929 1.8567 2.237 +3.1004 1.9728 2.1197 +3.1048 2.0683 1.9723 +3.1075 2.1531 1.8069 +3.1103 2.2367 1.6354 +3.1145 2.3291 1.4697 +3.1217 2.4398 1.3218 +3.139 2.467 1.2919 +3.1692 2.4928 1.2654 +3.187 2.5235 1.2391 +3.1733 2.5397 1.2278 +3.1463 2.5535 1.2214 +3.1327 2.5714 1.2145 +3.1425 2.6836 1.2011 +3.1536 2.8107 1.2254 +3.1653 2.9439 1.2631 +3.1767 3.0744 1.2893 +3.025 0.2593 0.5422 +3.0195 0.2893 0.5757 +3.0331 0.5035 0.7953 +3.0445 0.6914 1.0407 +3.0556 0.7179 1.0676 +3.0667 0.7439 1.0951 +3.0598 0.7531 1.1235 +3.0505 0.7604 1.153 +3.0427 0.8324 1.3097 +3.0503 0.912 1.4628 +3.062 0.995 1.6135 +3.0767 1.0174 1.6322 +3.0911 1.0399 1.6511 +3.0794 1.0478 1.6869 +3.0676 1.0557 1.7227 +3.0755 1.1919 1.9571 +3.0843 1.3366 2.185 +3.1008 1.3624 2.2009 +3.1175 1.3883 2.2167 +3.1036 1.3957 2.2475 +3.0897 1.4045 2.275 +3.0967 1.5123 2.3385 +3.1048 1.6422 2.3541 +3.1145 1.7797 2.3289 +3.1322 1.7944 2.3063 +3.15 1.8089 2.2827 +3.1438 1.8363 2.2838 +3.1302 1.8632 2.2937 +3.1235 1.887 2.2907 +3.1319 2.0037 2.1711 +3.1376 2.1014 2.0235 +3.1421 2.1896 1.8592 +3.1465 2.2773 1.6896 +3.1522 2.3738 1.5262 +3.1605 2.4883 1.3803 +3.1727 2.508 1.3448 +3.1935 2.5209 1.3055 +3.206 2.5432 1.2729 +3.1967 2.5591 1.2743 +3.1782 2.5755 1.2879 +3.1691 2.593 1.2912 +3.1781 2.6965 1.2749 +3.1885 2.816 1.3014 +3.1994 2.9419 1.3429 +3.2102 3.0649 1.3715 +1.4892 0.4883 0.8236 +1.486 0.4836 0.7849 +1.5107 0.4797 0.8159 +1.5377 0.5041 0.8464 +1.5085 0.5158 0.8569 +1.6542 0.7239 1.0553 +1.6892 0.7115 1.0443 +1.8251 0.8967 1.2705 +1.7843 0.9098 1.2818 +1.8045 0.9386 1.3034 +1.8366 0.9284 1.2948 +1.8477 0.9598 1.3195 +1.8244 0.967 1.3256 +1.8298 0.9747 1.3549 +1.861 0.9652 1.347 +1.8748 0.9675 1.3757 +1.8335 0.98 1.3861 +1.8838 1.0518 1.5387 +1.9393 1.0351 1.5249 +1.9972 1.1188 1.6697 +1.9422 1.1352 1.6832 +2.0036 1.223 1.8238 +2.0542 1.208 1.8117 +2.0597 1.2381 1.8281 +2.0221 1.2493 1.8372 +2.0404 1.2755 1.8508 +2.0654 1.268 1.8446 +2.0817 1.2697 1.8796 +2.0442 1.2809 1.8889 +2.0481 1.2864 1.9271 +2.0982 1.2713 1.9146 +2.1997 1.4094 2.1349 +2.146 1.4262 2.1491 +2.249 1.5734 2.3638 +2.3063 1.5548 2.3479 +2.3126 1.5887 2.3611 +2.2695 1.6027 2.3732 +2.2902 1.6321 2.3824 +2.3188 1.6228 2.3743 +2.3361 1.6222 2.4043 +2.294 1.6376 2.4179 +2.2988 1.6444 2.4504 +2.3543 1.6227 2.4309 +2.428 1.7238 2.4837 +2.3743 1.7524 2.5073 +2.4624 1.8781 2.5128 +2.5139 1.8409 2.4868 +2.602 1.9627 2.4483 +2.5538 2.0086 2.4737 +2.5618 2.0201 2.4432 +2.5978 1.9852 2.4243 +2.5932 2.0075 2.3992 +2.5695 2.0311 2.4116 +2.5883 2.0579 2.4122 +2.6173 2.0268 2.3977 +2.6471 2.0416 2.4051 +2.6078 2.0857 2.424 +2.6242 2.1091 2.4203 +2.6688 2.0573 2.3998 +2.7386 2.1538 2.2693 +2.6924 2.2066 2.2891 +2.7478 2.2857 2.1323 +2.7957 2.2303 2.1128 +2.8461 2.2966 1.9406 +2.7965 2.3553 1.9603 +2.845 2.4245 1.7834 +2.896 2.3622 1.7631 +2.9515 2.4366 1.5909 +2.8994 2.5022 1.6119 +2.966 2.5973 1.4563 +3.0185 2.5292 1.4344 +3.0213 2.5515 1.3971 +2.9751 2.6104 1.4171 +2.9787 2.6154 1.372 +3.0125 2.5734 1.3566 +3.017 2.5983 1.322 +2.9895 2.631 1.3351 +2.9998 2.6456 1.3394 +3.0354 2.6059 1.3218 +3.0616 2.6089 1.334 +3.0108 2.6613 1.36 +3.0216 2.6768 1.3662 +3.0811 2.6181 1.3357 +3.1422 2.7054 1.3097 +3.0804 2.7607 1.3391 +3.147 2.8558 1.3559 +3.211 2.8035 1.3252 +3.2846 2.9086 1.3549 +3.2188 2.9584 1.3877 +3.2929 3.0642 1.4059 +3.3605 3.0169 1.3718 +3.2929 3.0642 1.2905 +1.5256 0.4847 0.7973 +1.5581 0.511 0.8211 +1.7151 0.7227 1.0178 +1.8565 0.912 1.2434 +1.8615 0.9408 1.2738 +1.8659 0.9691 1.305 +1.8854 0.9778 1.3278 +1.9072 0.9843 1.3507 +1.9832 1.0579 1.4917 +2.0408 1.1417 1.6373 +2.0944 1.2293 1.7823 +2.0896 1.2539 1.8062 +2.0852 1.2784 1.8298 +2.1113 1.2851 1.8572 +2.1377 1.2919 1.8844 +2.2415 1.4303 2.1005 +2.3503 1.5761 2.3093 +2.3456 1.6046 2.332 +2.3408 1.6333 2.3547 +2.3666 1.6344 2.3707 +2.3934 1.6367 2.3839 +2.458 1.7231 2.4262 +2.5336 1.8232 2.4237 +2.6105 1.9274 2.3872 +2.6037 1.958 2.3787 +2.5965 1.9883 2.3693 +2.6186 1.9986 2.3628 +2.6475 2.0002 2.3593 +2.668 2.0079 2.3496 +2.7381 2.1035 2.2215 +2.7947 2.1773 2.0655 +2.844 2.2396 1.8925 +2.8922 2.3005 1.7135 +2.9457 2.3702 1.5395 +3.0107 2.4588 1.3815 +3.0153 2.4911 1.3488 +3.0091 2.531 1.3197 +3.0158 2.5668 1.2904 +3.0372 2.5709 1.2777 +3.067 2.5647 1.2702 +3.0897 2.5706 1.2617 +3.1566 2.6661 1.2377 +3.23 2.771 1.2504 +3.3079 2.8823 1.2756 +3.3884 2.9973 1.2893 +1.5252 0.5004 0.7787 +1.5576 0.5325 0.7959 +1.7168 0.7509 0.9913 +1.8601 0.9468 1.2162 +1.8646 0.9684 1.2529 +1.8684 0.9894 1.2904 +1.8889 1.0051 1.3087 +1.9119 1.0205 1.3256 +1.9896 1.1069 1.4585 +2.0474 1.1904 1.6049 +2.1006 1.2743 1.753 +2.0942 1.2873 1.7842 +2.0882 1.3005 1.815 +2.1157 1.3182 1.8347 +2.1435 1.336 1.8542 +2.2469 1.4768 2.0661 +2.3552 1.6247 2.2707 +2.3492 1.6411 2.3029 +2.3432 1.6576 2.3352 +2.3676 1.6672 2.3371 +2.3931 1.6781 2.337 +2.4469 1.751 2.3693 +2.5102 1.8356 2.3612 +2.5744 1.9234 2.3261 +2.5761 1.9543 2.333 +2.5773 1.9848 2.3394 +2.5916 1.9901 2.3279 +2.6085 1.9864 2.3133 +2.6218 1.9901 2.2994 +2.6912 2.086 2.174 +2.7456 2.1588 2.0188 +2.7917 2.2189 1.8453 +2.8362 2.2768 1.6649 +2.8859 2.343 1.489 +2.9475 2.428 1.329 +2.9607 2.4651 1.3009 +2.9705 2.5134 1.2829 +2.9866 2.5549 1.2588 +3.0038 2.5609 1.2339 +3.0239 2.5551 1.2072 +3.0423 2.5629 1.1886 +3.1142 2.6655 1.1647 +3.1924 2.7771 1.1744 +3.2751 2.8951 1.1958 +3.3605 3.0169 1.2068 +1.5098 0.5176 0.771 +1.5367 0.556 0.7854 +1.6931 0.7795 0.9803 +1.8339 0.9806 1.205 +1.8441 0.9951 1.2442 +1.8537 1.0088 1.2844 +1.8693 1.0311 1.3008 +1.886 1.055 1.3152 +1.9549 1.1533 1.4447 +2.0131 1.2365 1.5915 +2.0693 1.3167 1.7409 +2.0708 1.3189 1.7751 +2.0726 1.3214 1.8089 +2.0923 1.3496 1.8254 +2.1122 1.378 1.8417 +2.2127 1.5215 2.0518 +2.3182 1.6722 2.2547 +2.3214 1.6768 2.2909 +2.3246 1.6814 2.3271 +2.3387 1.7015 2.3235 +2.3536 1.7228 2.3176 +2.4018 1.7916 2.3459 +2.4576 1.8712 2.3353 +2.5148 1.953 2.3008 +2.531 1.9761 2.3141 +2.547 1.999 2.327 +2.5523 2.0064 2.3134 +2.5536 2.0084 2.2941 +2.5578 2.0143 2.2787 +2.6259 2.1116 2.1546 +2.6775 2.1853 1.9999 +2.7199 2.2459 1.8262 +2.7606 2.3039 1.6451 +2.8067 2.3699 1.4683 +2.8658 2.4542 1.3073 +2.8897 2.4884 1.281 +2.9195 2.5309 1.2675 +2.9465 2.5696 1.2457 +2.9544 2.5808 1.2165 +2.9574 2.585 1.1817 +2.967 2.5988 1.1586 +3.0408 2.7042 1.1347 +3.121 2.8187 1.1431 +3.2057 2.9397 1.1628 +3.2929 3.0642 1.1727 +1.4883 0.5262 0.7787 +1.5074 0.5677 0.7959 +1.6582 0.7919 0.9913 +1.7932 0.9936 1.2162 +1.812 1.0053 1.2529 +1.8304 1.016 1.2904 +1.8382 1.0406 1.3087 +1.8448 1.0675 1.3256 +1.8994 1.1701 1.4585 +1.9581 1.2529 1.6049 +2.0187 1.3317 1.753 +2.0332 1.33 1.7842 +2.0476 1.3289 1.815 +2.0548 1.3608 1.8347 +2.0621 1.3931 1.8542 +2.159 1.5383 2.0661 +2.2609 1.6907 2.2707 +2.2784 1.6907 2.3029 +2.2959 1.6907 2.3352 +2.2966 1.7169 2.3371 +2.2982 1.7446 2.337 +2.3483 1.8201 2.3693 +2.4061 1.9085 2.3612 +2.4667 1.9989 2.3261 +2.4951 2.011 2.333 +2.5233 2.0226 2.3394 +2.5234 2.0378 2.3279 +2.5142 2.0525 2.3133 +2.5132 2.0662 2.2994 +2.5795 2.1642 2.174 +2.6293 2.2402 2.0188 +2.67 2.3041 1.8453 +2.7092 2.3657 1.6649 +2.7544 2.4351 1.489 +2.8132 2.522 1.329 +2.8435 2.5471 1.3009 +2.8856 2.5729 1.2829 +2.9191 2.6022 1.2588 +2.9188 2.6204 1.2339 +2.9065 2.6372 1.2072 +2.9075 2.6572 1.1886 +2.9794 2.7599 1.1647 +3.0574 2.8716 1.1744 +3.14 2.9896 1.1958 +3.2253 3.1115 1.2068 +1.4734 0.5212 0.7973 +1.4871 0.5608 0.8211 +1.6322 0.7807 1.0178 +1.7618 0.9783 1.2434 +1.7871 0.9929 1.2738 +1.8122 1.0067 1.305 +1.8137 1.028 1.3278 +1.8123 1.0507 1.3507 +1.8556 1.1473 1.4917 +1.9146 1.2301 1.6373 +1.9786 1.3104 1.7823 +2.0033 1.3143 1.8062 +2.0278 1.3185 1.8298 +2.0252 1.3454 1.8572 +2.0225 1.3725 1.8844 +2.1171 1.5174 2.1005 +2.2169 1.6694 2.3093 +2.2453 1.6748 2.332 +2.2739 1.6802 2.3547 +2.2662 1.7047 2.3707 +2.2591 1.7307 2.3839 +2.3183 1.8209 2.4262 +2.3864 1.9262 2.4237 +2.4581 2.0342 2.3872 +2.4891 2.0382 2.3787 +2.5201 2.0418 2.3693 +2.5222 2.0662 2.3628 +2.5138 2.0938 2.3593 +2.514 2.1157 2.3496 +2.5798 2.2143 2.2215 +2.6299 2.2927 2.0655 +2.6716 2.3603 1.8925 +2.7123 2.4265 1.7135 +2.7595 2.5006 1.5395 +2.8205 2.592 1.3815 +2.8493 2.6073 1.3488 +2.8889 2.6152 1.3197 +2.9203 2.6337 1.2904 +2.9169 2.6552 1.2777 +2.9007 2.6811 1.2702 +2.8986 2.7044 1.2617 +2.9655 2.7999 1.2377 +3.0389 2.9048 1.2504 +3.1169 3.0161 1.2756 +3.1974 3.1311 1.2893 +1.4738 0.5055 0.8159 +1.4875 0.5393 0.8464 +1.6306 0.7525 1.0443 +1.7581 0.9436 1.2705 +1.784 0.9653 1.2948 +1.8097 0.9864 1.3195 +1.8102 1.0007 1.347 +1.8076 1.0145 1.3757 +1.8491 1.0982 1.5249 +1.908 1.1813 1.6697 +1.9723 1.2654 1.8117 +1.9987 1.2808 1.8281 +2.0249 1.2964 1.8446 +2.0208 1.3123 1.8796 +2.0167 1.3283 1.9146 +2.1118 1.4709 2.1349 +2.212 1.6209 2.3479 +2.2417 1.6383 2.3611 +2.2716 1.6559 2.3743 +2.2651 1.6719 2.4043 +2.2593 1.6892 2.4309 +2.3291 1.793 2.4837 +2.4098 1.9138 2.4868 +2.4942 2.0382 2.4483 +2.5167 2.042 2.4243 +2.5392 2.0453 2.3992 +2.5492 2.0745 2.3977 +2.5528 2.1076 2.4051 +2.5602 2.1334 2.3998 +2.6269 2.2319 2.2693 +2.6794 2.3117 2.1128 +2.7244 2.3818 1.9406 +2.769 2.4512 1.7631 +2.8199 2.5287 1.5909 +2.884 2.6233 1.4344 +2.904 2.6336 1.3971 +2.9276 2.6329 1.3566 +2.9495 2.6456 1.322 +2.9503 2.6654 1.3218 +2.9441 2.6911 1.334 +2.9461 2.7126 1.3357 +3.0073 2.7999 1.3097 +3.076 2.8981 1.3252 +3.1495 3.0032 1.3549 +3.2253 3.1115 1.3718 +0.2555 3.8781 0.8236 +0.25 3.8796 0.7849 +0.2547 3.855 0.8159 +0.2869 3.8379 0.8464 +0.2879 3.8694 0.8569 +0.5332 3.8037 1.0553 +0.5335 3.7665 1.0443 +0.7541 3.7022 1.2705 +0.7524 3.7449 1.2818 +0.7864 3.7358 1.3034 +0.7879 3.7022 1.2948 +0.8212 3.7025 1.3195 +0.8199 3.7268 1.3256 +0.829 3.7244 1.3549 +0.8307 3.6919 1.347 +0.8376 3.6797 1.3757 +0.8352 3.7227 1.3861 +0.9199 3.7 1.5387 +0.9232 3.6422 1.5249 +1.0217 3.6164 1.6697 +1.0183 3.6737 1.6832 +1.1217 3.646 1.8238 +1.125 3.5933 1.8117 +1.1552 3.5985 1.8281 +1.1528 3.6376 1.8372 +1.1837 3.6294 1.8508 +1.1852 3.6033 1.8446 +1.1923 3.5886 1.8796 +1.1901 3.6276 1.8889 +1.1966 3.6259 1.9271 +1.1995 3.5737 1.9146 +1.364 3.5255 2.1349 +1.3614 3.5817 2.1491 +1.535 3.5352 2.3638 +1.5371 3.4751 2.3479 +1.5711 3.4808 2.3611 +1.5695 3.526 2.3732 +1.6042 3.5167 2.3824 +1.6053 3.4865 2.3743 +1.6106 3.4701 2.4043 +1.6106 3.515 2.4179 +1.6187 3.5128 2.4504 +1.6173 3.4532 2.4309 +1.7375 3.4185 2.4837 +1.746 3.4787 2.5073 +1.8943 3.439 2.5128 +1.877 3.3778 2.4868 +2.0216 3.3367 2.4483 +2.0482 3.3977 2.4737 +2.0617 3.3941 2.4432 +2.0412 3.3484 2.4243 +2.0606 3.3602 2.3992 +2.0747 3.3906 2.4116 +2.1063 3.3821 2.4122 +2.087 3.3443 2.3977 +2.1111 3.3213 2.4051 +2.1391 3.3734 2.424 +2.1667 3.366 2.4203 +2.1333 3.3063 2.3998 +2.2478 3.2737 2.2693 +2.2817 3.3352 2.2891 +2.3749 3.3102 2.1323 +2.3393 3.2463 2.1128 +2.4188 3.2215 1.9406 +2.457 3.2882 1.9603 +2.5386 3.2663 1.7834 +2.4975 3.197 1.7631 +2.5863 3.1704 1.5909 +2.6302 3.2418 1.6119 +2.7423 3.2117 1.4563 +2.6963 3.1391 1.4344 +2.7182 3.1441 1.3971 +2.7578 3.2076 1.4171 +2.7637 3.206 1.372 +2.7358 3.1598 1.3566 +2.7608 3.1641 1.322 +2.782 3.2011 1.3351 +2.7993 3.1965 1.3394 +2.7742 3.1495 1.3218 +2.7859 3.1258 1.334 +2.8178 3.1915 1.36 +2.8361 3.1866 1.3662 +2.8012 3.1107 1.3357 +2.9042 3.0831 1.3097 +2.935 3.1601 1.3391 +3.0472 3.13 1.3559 +3.0199 3.052 1.3252 +3.1438 3.0188 1.3549 +3.1681 3.0976 1.3877 +3.2715 2.9845 1.3718 +0.2645 3.8427 0.7973 +0.3004 3.8212 0.8211 +0.553 3.746 1.0178 +0.7792 3.6779 1.2434 +0.808 3.683 1.2738 +0.8361 3.6885 1.305 +0.8509 3.6732 1.3278 +0.8645 3.6549 1.3507 +0.9597 3.6088 1.4917 +1.0581 3.5832 1.6373 +1.1587 3.5628 1.7823 +1.1802 3.5758 1.8062 +1.2017 3.5883 1.8298 +1.217 3.566 1.8572 +1.2323 3.5435 1.8844 +1.3979 3.4934 2.1005 +1.5721 3.441 2.3093 +1.5973 3.4552 2.332 +1.6227 3.4695 2.3547 +1.6325 3.4456 2.3707 +1.6438 3.4212 2.3839 +1.7472 3.3901 2.4262 +1.867 3.3532 2.4237 +1.9913 3.3166 2.3872 +2.0177 3.3335 2.3787 +2.0437 3.3506 2.3693 +2.061 3.3333 2.3628 +2.0723 3.3068 2.3593 +2.0866 3.2902 2.3496 +2.2004 3.2569 2.2215 +2.2891 3.229 2.0655 +2.3645 3.204 1.8925 +2.4382 3.1795 1.7135 +2.522 3.1531 1.5395 +2.6275 3.1223 1.3815 +2.6594 3.1291 1.3488 +2.6948 3.1485 1.3197 +2.7307 3.1545 1.2904 +2.7419 3.1358 1.2777 +2.7462 3.1056 1.2702 +2.7596 3.0864 1.2617 +2.8722 3.0562 1.2377 +2.9958 3.023 1.2504 +3.1271 2.9879 1.2756 +3.2627 2.9515 1.2893 +0.2791 3.8484 0.7787 +0.3204 3.8289 0.7959 +0.58 3.7541 0.9913 +0.8131 3.6863 1.2162 +0.835 3.6895 1.2529 +0.856 3.6931 1.2904 +0.8777 3.6793 1.3087 +0.9001 3.6629 1.3256 +1.0079 3.6195 1.4585 +1.1062 3.5937 1.6049 +1.2032 3.5724 1.753 +1.2132 3.5829 1.7842 +1.2235 3.5931 1.815 +1.2496 3.5732 1.8347 +1.2758 3.5532 1.8542 +1.4434 3.5042 2.0661 +1.6195 3.453 2.2707 +1.6329 3.4642 2.3029 +1.6463 3.4755 2.3352 +1.6637 3.4559 2.3371 +1.6827 3.4357 2.337 +1.7696 3.41 2.3693 +1.8707 3.3795 2.3612 +1.9752 3.3492 2.3261 +2.0047 3.3582 2.333 +2.0338 3.3674 2.3394 +2.0437 3.3559 2.3279 +2.0461 3.3387 2.3133 +2.0541 3.3275 2.2994 +2.1679 3.2951 2.174 +2.2549 3.2688 2.0188 +2.3271 3.2461 1.8453 +2.3967 3.224 1.6649 +2.476 3.2 1.489 +2.5769 3.1712 1.329 +2.6163 3.1714 1.3009 +2.665 3.1787 1.2829 +2.7096 3.1778 1.2588 +2.721 3.1637 1.2339 +2.7224 3.1429 1.2072 +2.7361 3.1282 1.1886 +2.8571 3.0957 1.1647 +2.9887 3.0604 1.1744 +3.1279 3.0231 1.1958 +3.2716 2.9845 1.2068 +0.29 3.8688 0.771 +0.3353 3.8567 0.7854 +0.5988 3.7861 0.9803 +0.8359 3.7225 1.205 +0.8531 3.718 1.2442 +0.8693 3.7136 1.2844 +0.8955 3.7066 1.3008 +0.9237 3.699 1.3152 +1.0396 3.668 1.4447 +1.1377 3.6417 1.5915 +1.2323 3.6163 1.7409 +1.2348 3.6157 1.7751 +1.2379 3.6148 1.8089 +1.271 3.606 1.8254 +1.3045 3.597 1.8417 +1.4738 3.5516 2.0518 +1.6515 3.504 2.2547 +1.6569 3.5026 2.2909 +1.6623 3.5011 2.3271 +1.6861 3.4948 2.3235 +1.7112 3.488 2.3176 +1.7922 3.4663 2.3459 +1.8862 3.4411 2.3353 +1.9826 3.4153 2.3008 +2.0099 3.408 2.3141 +2.0368 3.4008 2.327 +2.0456 3.3984 2.3134 +2.048 3.3978 2.2941 +2.0549 3.3959 2.2787 +2.1696 3.3652 2.1546 +2.2565 3.3419 1.9999 +2.328 3.3228 1.8262 +2.3964 3.3044 1.6451 +2.4742 3.2836 1.4683 +2.5736 3.2569 1.3073 +2.6139 3.2461 1.281 +2.664 3.2327 1.2675 +2.7096 3.2205 1.2457 +2.7229 3.2169 1.2165 +2.7279 3.2156 1.1817 +2.7441 3.2113 1.1586 +2.8684 3.178 1.1347 +3.0035 3.1418 1.1431 +3.1461 3.1035 1.1628 +0.2908 3.8919 0.7787 +0.3363 3.8882 0.7959 +0.5985 3.8232 0.9913 +0.8343 3.7653 1.2162 +0.8516 3.7516 1.2529 +0.868 3.738 1.2904 +0.8938 3.7391 1.3087 +0.9214 3.7421 1.3256 +1.0364 3.7258 1.4585 +1.1344 3.699 1.6049 +1.2291 3.669 1.753 +1.2325 3.6548 1.7842 +1.2363 3.6409 1.815 +1.2688 3.645 1.8347 +1.3016 3.6492 1.8542 +1.4712 3.6079 2.0661 +1.6493 3.5642 2.2707 +1.6553 3.5478 2.3029 +1.6613 3.5313 2.3352 +1.6861 3.5396 2.3371 +1.7126 3.5476 2.337 +1.8008 3.5264 2.3693 +1.9036 3.5023 2.3612 +2.0092 3.4762 2.3261 +2.0303 3.4537 2.333 +2.0509 3.4311 2.3394 +2.0652 3.4362 2.3279 +2.0759 3.4499 2.3133 +2.0884 3.4556 2.2994 +2.2032 3.4268 2.174 +2.2916 3.406 2.0188 +2.3656 3.3896 1.8453 +2.4369 3.3738 1.6649 +2.5175 3.3551 1.489 +2.6193 3.3296 1.329 +2.6533 3.3096 1.3009 +2.6919 3.2789 1.2829 +2.7309 3.2575 1.2588 +2.7479 3.2639 1.2339 +2.7595 3.2813 1.2072 +2.7787 3.2872 1.1886 +2.8997 3.2548 1.1647 +3.0313 3.2196 1.1744 +3.1706 3.1823 1.1958 +3.3143 3.1439 1.2068 +0.281 3.9042 0.7973 +0.3228 3.9049 0.8211 +0.5791 3.8437 1.0178 +0.8091 3.7896 1.2434 +0.8315 3.7708 1.2738 +0.8531 3.7519 1.305 +0.8736 3.7578 1.3278 +0.8945 3.7668 1.3507 +1 3.7592 1.4917 +1.098 3.7321 1.6373 +1.1953 3.6994 1.7823 +1.2074 3.6775 1.8062 +1.2198 3.6559 1.8298 +1.2442 3.6676 1.8572 +1.2687 3.6794 1.8844 +1.4372 3.64 2.1005 +1.6143 3.5982 2.3093 +1.629 3.5734 2.332 +1.6438 3.5483 2.3547 +1.6642 3.564 2.3707 +1.6862 3.5796 2.3839 +1.7913 3.5548 2.4262 +1.9135 3.5268 2.4237 +2.0395 3.4964 2.3872 +2.0539 3.4686 2.3787 +2.0678 3.4408 2.3693 +2.0915 3.4471 2.3628 +2.1146 3.4644 2.3593 +2.1352 3.4717 2.3496 +2.2504 3.4436 2.2215 +2.3412 3.4234 2.0655 +2.419 3.4073 1.8925 +2.4951 3.3917 1.7135 +2.5808 3.3727 1.5395 +2.6876 3.3466 1.3815 +2.7119 3.3248 1.3488 +2.7328 3.2903 1.3197 +2.7609 3.2671 1.2904 +2.7799 3.2777 1.2777 +2.7988 3.3017 1.2702 +2.8199 3.3117 1.2617 +2.9326 3.2815 1.2377 +3.0562 3.2484 1.2504 +3.1875 3.2132 1.2756 +3.3231 3.1769 1.2893 +0.2664 3.8984 0.8159 +0.3028 3.8971 0.8464 +0.5521 3.8356 1.0443 +0.7752 3.7811 1.2705 +0.8045 3.7642 1.2948 +0.8332 3.7473 1.3195 +0.8468 3.7517 1.347 +0.8588 3.7588 1.3757 +0.9517 3.7485 1.5249 +1.0499 3.7216 1.6697 +1.1509 3.6899 1.8117 +1.1744 3.6704 1.8281 +1.198 3.6511 1.8446 +1.2116 3.6604 1.8796 +1.2253 3.6697 1.9146 +1.3918 3.6292 2.1349 +1.5669 3.5862 2.3479 +1.5935 3.5643 2.3611 +1.6202 3.5423 2.3743 +1.633 3.5538 2.4043 +1.6473 3.5652 2.4309 +1.7687 3.535 2.4837 +1.9099 3.5006 2.4868 +2.0556 3.4638 2.4483 +2.0668 3.4439 2.4243 +2.0777 3.424 2.3992 +2.1085 3.4246 2.3977 +2.1409 3.4325 2.4051 +2.1676 3.4343 2.3998 +2.283 3.4053 2.2693 +2.376 3.3834 2.1128 +2.4573 3.365 1.9406 +2.5376 3.3468 1.7631 +2.6279 3.3255 1.5909 +2.7388 3.2976 1.4344 +2.7553 3.2824 1.3971 +2.7626 3.26 1.3566 +2.7821 3.2438 1.322 +2.801 3.2497 1.3218 +2.8231 3.2643 1.334 +2.8439 3.2698 1.3357 +2.9468 3.2422 1.3097 +3.0626 3.2112 1.3252 +3.1865 3.1781 1.3549 +3.3142 3.1439 1.3718 +1.2968 5.0603 0.5494 +1.2954 5.0617 0.5103 +1.2847 5.0407 0.5422 +1.2998 5.0141 0.5757 +1.3163 5.0408 0.5854 +1.4663 4.8908 0.8053 +1.4479 4.8588 0.7953 +1.5774 4.7222 1.0407 +1.5976 4.7595 1.0506 +1.6187 4.7384 1.0753 +1.6029 4.709 1.0676 +1.6282 4.6963 1.0951 +1.6395 4.7176 1.1003 +1.6438 4.7133 1.1304 +1.6288 4.6848 1.1235 +1.6263 4.6732 1.153 +1.6462 4.7109 1.162 +1.6933 4.6638 1.3217 +1.6667 4.613 1.3097 +1.7236 4.5569 1.4628 +1.7498 4.6073 1.4745 +1.8099 4.5472 1.624 +1.7859 4.5009 1.6135 +1.8116 4.4931 1.6322 +1.8296 4.5275 1.6401 +1.8491 4.508 1.6564 +1.8372 4.4852 1.6511 +1.8332 4.4716 1.6869 +1.8512 4.5059 1.695 +1.8533 4.5038 1.7336 +1.8293 4.4579 1.7227 +1.9229 4.3588 1.9571 +1.9492 4.4079 1.9696 +2.0512 4.3059 2.1992 +2.0226 4.2535 2.185 +2.0519 4.2444 2.2009 +2.0733 4.2838 2.2116 +2.0956 4.2615 2.2239 +2.0813 4.2352 2.2167 +2.0754 4.2207 2.2475 +2.0979 4.2592 2.2599 +2.1014 4.2557 2.293 +2.0704 4.205 2.275 +2.1451 4.1269 2.3385 +2.1818 4.1753 2.3611 +2.2788 4.0783 2.38 +2.2348 4.0326 2.3541 +2.3306 3.9335 2.3289 +2.382 3.9751 2.3549 +2.3925 3.9646 2.3258 +2.3536 3.9336 2.3063 +2.3765 3.934 2.2827 +2.4028 3.9543 2.2955 +2.4235 3.9336 2.299 +2.3894 3.909 2.2838 +2.3963 3.8796 2.2937 +2.4444 3.9127 2.3137 +2.4627 3.8944 2.3125 +2.4065 3.8571 2.2907 +2.4879 3.7731 2.1711 +2.5454 3.8117 2.1921 +2.6153 3.7418 2.0443 +2.5551 3.7019 2.0235 +2.6152 3.6373 1.8592 +2.6788 3.6783 1.8803 +2.7421 3.615 1.7115 +2.6749 3.5729 1.6896 +2.7413 3.5026 1.5262 +2.8117 3.5454 1.549 +2.894 3.4631 1.4041 +2.8213 3.4202 1.3803 +2.8433 3.413 1.3448 +2.9063 3.4508 1.3664 +2.9127 3.4444 1.322 +2.8675 3.4165 1.3055 +2.8915 3.4075 1.2729 +2.9268 3.4303 1.2868 +2.9378 3.4193 1.2927 +2.8945 3.3893 1.2743 +2.8909 3.3649 1.2879 +2.9489 3.4082 1.3149 +2.9605 3.3966 1.3228 +2.8951 3.3456 1.2912 +2.9686 3.2721 1.2749 +3.0313 3.3258 1.305 +3.1138 3.2433 1.3325 +3.0534 3.1872 1.3014 +3.1427 3.0978 1.3429 +3.2011 3.156 1.3758 +3.2864 3.0707 1.4055 +3.23 3.0105 1.3715 +3.2928 3.0643 1.2905 +1.2871 5.025 0.5247 +1.3032 4.9926 0.552 +1.4541 4.8314 0.7708 +1.5863 4.6891 1.0161 +1.6101 4.6827 1.0488 +1.6336 4.6771 1.082 +1.6362 4.659 1.1064 +1.6362 4.639 1.1307 +1.6801 4.5668 1.2803 +1.7371 4.511 1.4342 +1.7985 4.4586 1.5876 +1.821 4.4617 1.6128 +1.8433 4.4643 1.638 +1.8423 4.4404 1.667 +1.8414 4.4163 1.6959 +1.9351 4.3147 1.9263 +2.0349 4.2071 2.1501 +2.061 4.2096 2.1746 +2.0873 4.212 2.199 +2.0819 4.1885 2.2162 +2.0775 4.1637 2.2309 +2.1412 4.0953 2.2825 +2.2175 4.0125 2.2909 +2.2994 3.9261 2.2658 +2.3296 3.9286 2.2591 +2.3597 3.9314 2.2516 +2.3649 3.909 2.247 +2.3603 3.8814 2.2451 +2.3635 3.8607 2.237 +2.4439 3.7765 2.1197 +2.5087 3.7061 1.9723 +2.5653 3.643 1.8069 +2.6211 3.5807 1.6354 +2.6837 3.5127 1.4697 +2.7604 3.4325 1.3218 +2.7911 3.4227 1.2919 +2.8309 3.4224 1.2654 +2.8642 3.4104 1.2391 +2.8642 3.3891 1.2278 +2.8523 3.3612 1.2214 +2.8534 3.3387 1.2145 +2.9331 3.2591 1.2011 +3.0233 3.1689 1.2254 +3.1178 3.0744 1.2631 +3.2104 2.9817 1.2893 +1.3029 5.0225 0.5072 +1.3247 4.9892 0.5282 +1.4815 4.8252 0.7464 +1.6194 4.6802 0.9916 +1.6364 4.6756 1.0299 +1.6528 4.6716 1.069 +1.662 4.6516 1.0894 +1.6704 4.6291 1.1084 +1.7263 4.5534 1.2508 +1.783 4.4975 1.4055 +1.8409 4.446 1.5618 +1.8525 4.4523 1.5934 +1.8641 4.4582 1.6249 +1.8735 4.4313 1.6471 +1.8831 4.4041 1.6691 +1.9792 4.3024 1.8954 +2.0813 4.1948 2.1151 +2.0959 4.2004 2.1482 +2.1105 4.2059 2.1813 +2.1141 4.182 2.1851 +2.1187 4.1567 2.187 +2.1727 4.0994 2.227 +2.2376 4.0297 2.2282 +2.3069 3.9572 2.2028 +2.3347 3.9525 2.2119 +2.3623 3.9482 2.2206 +2.3648 3.9336 2.2102 +2.3586 3.9173 2.1962 +2.3599 3.9037 2.1832 +2.4406 3.8204 2.0686 +2.5048 3.7522 1.9219 +2.56 3.6923 1.7556 +2.614 3.6338 1.5823 +2.6743 3.5697 1.4142 +2.7485 3.4931 1.2639 +2.7815 3.4748 1.2393 +2.825 3.4589 1.2254 +2.8613 3.4376 1.2052 +2.8645 3.4194 1.1817 +2.8563 3.3996 1.1557 +2.8605 3.3803 1.1387 +2.9457 3.2951 1.1261 +3.0412 3.1994 1.1483 +3.1411 3.0994 1.1829 +3.2392 3.0013 1.2071 +1.3225 5.0346 0.5 +1.3514 5.0057 0.5185 +1.5135 4.8436 0.7364 +1.6567 4.7004 0.9816 +1.6657 4.6914 1.0223 +1.6741 4.683 1.0638 +1.6904 4.6667 1.0825 +1.7082 4.6489 1.0994 +1.7771 4.58 1.2389 +1.8333 4.5238 1.3939 +1.8871 4.47 1.5513 +1.8869 4.4702 1.5856 +1.887 4.4701 1.6196 +1.9078 4.4493 1.639 +1.9289 4.4282 1.6582 +2.0284 4.3287 1.8828 +2.1337 4.2234 2.1009 +2.1353 4.2218 2.1375 +2.1368 4.2203 2.1741 +2.1526 4.2045 2.1727 +2.1694 4.1877 2.1691 +2.221 4.1361 2.2046 +2.2833 4.0738 2.2025 +2.3485 4.0086 2.1768 +2.3656 3.9915 2.1925 +2.3826 3.9745 2.2077 +2.3892 3.9679 2.195 +2.3918 3.9653 2.176 +2.3972 3.9599 2.1613 +2.4793 3.8778 2.048 +2.5449 3.8122 1.9017 +2.6015 3.7556 1.7351 +2.6565 3.7006 1.5609 +2.7173 3.6398 1.3918 +2.7915 3.5656 1.2404 +2.8194 3.5377 1.2178 +2.853 3.5041 1.2089 +2.8842 3.4729 1.1913 +2.8945 3.4626 1.1634 +2.8997 3.4574 1.1291 +2.9116 3.4455 1.1076 +2.9989 3.3582 1.0954 +3.0969 3.2602 1.1166 +3.1991 3.158 1.1497 +3.2994 3.0577 1.1731 +1.3346 5.0542 0.5072 +1.3679 5.0324 0.5282 +1.5319 4.8756 0.7464 +1.6769 4.7377 0.9916 +1.6815 4.7207 1.0299 +1.6855 4.7043 1.069 +1.7055 4.6951 1.0894 +1.728 4.6867 1.1084 +1.8037 4.6308 1.2508 +1.8596 4.5741 1.4055 +1.9111 4.5162 1.5618 +1.9048 4.5046 1.5934 +1.8989 4.493 1.6249 +1.9258 4.4836 1.6471 +1.953 4.474 1.6691 +2.0547 4.3779 1.8954 +2.1623 4.2758 2.1151 +2.1567 4.2612 2.1482 +2.1512 4.2466 2.1813 +2.1751 4.243 2.1851 +2.2004 4.2384 2.187 +2.2577 4.1844 2.227 +2.3274 4.1195 2.2282 +2.3999 4.0502 2.2028 +2.4046 4.0224 2.2119 +2.4089 3.9948 2.2206 +2.4235 3.9923 2.2102 +2.4398 3.9985 2.1962 +2.4534 3.9972 2.1832 +2.5367 3.9165 2.0686 +2.6049 3.8523 1.9219 +2.6648 3.7971 1.7556 +2.7233 3.7431 1.5823 +2.7874 3.6828 1.4142 +2.864 3.6086 1.2639 +2.8823 3.5756 1.2393 +2.8982 3.5321 1.2254 +2.9195 3.4958 1.2052 +2.9377 3.4926 1.1817 +2.9575 3.5008 1.1557 +2.9768 3.4966 1.1387 +3.062 3.4114 1.1261 +3.1577 3.3159 1.1483 +3.2577 3.216 1.1829 +3.3558 3.1179 1.2071 +1.3321 5.07 0.5247 +1.3645 5.0539 0.552 +1.5257 4.903 0.7708 +1.668 4.7708 1.0161 +1.6744 4.747 1.0488 +1.68 4.7235 1.082 +1.6981 4.7209 1.1064 +1.7181 4.7209 1.1307 +1.7903 4.677 1.2803 +1.8461 4.62 1.4342 +1.8985 4.5586 1.5876 +1.8954 4.5361 1.6128 +1.8928 4.5138 1.638 +1.9167 4.5148 1.667 +1.9408 4.5157 1.6959 +2.0424 4.422 1.9263 +2.15 4.3222 2.1501 +2.1475 4.2961 2.1746 +2.1451 4.2698 2.199 +2.1686 4.2752 2.2162 +2.1934 4.2796 2.2309 +2.2618 4.2159 2.2825 +2.3446 4.1396 2.2909 +2.431 4.0577 2.2658 +2.4285 4.0275 2.2591 +2.4257 3.9974 2.2516 +2.4481 3.9922 2.247 +2.4757 3.9968 2.2451 +2.4964 3.9936 2.237 +2.5806 3.9132 2.1197 +2.651 3.8484 1.9723 +2.7141 3.7918 1.8069 +2.7764 3.736 1.6354 +2.8444 3.6734 1.4697 +2.9246 3.5967 1.3218 +2.9344 3.566 1.2919 +2.9347 3.5262 1.2654 +2.9467 3.4929 1.2391 +2.968 3.4929 1.2278 +2.9959 3.5048 1.2214 +3.0184 3.5037 1.2145 +3.098 3.424 1.2011 +3.1882 3.3338 1.2254 +3.2827 3.2393 1.2631 +3.3754 3.1467 1.2893 +1.3164 5.0724 0.5422 +1.343 5.0573 0.5757 +1.4983 4.9092 0.7953 +1.6349 4.7797 1.0407 +1.6481 4.7542 1.0676 +1.6608 4.7289 1.0951 +1.6723 4.7283 1.1235 +1.6839 4.7308 1.153 +1.7441 4.6904 1.3097 +1.8002 4.6335 1.4628 +1.8562 4.5712 1.6135 +1.864 4.5455 1.6322 +1.8719 4.5199 1.6511 +1.8855 4.5239 1.6869 +1.8992 4.5278 1.7227 +1.9983 4.4342 1.9571 +2.1036 4.3345 2.185 +2.1127 4.3052 2.2009 +2.1219 4.2758 2.2167 +2.1364 4.2817 2.2475 +2.1521 4.2867 2.275 +2.2302 4.212 2.3385 +2.3245 4.1223 2.3541 +2.4236 4.0265 2.3289 +2.4235 4.0035 2.3063 +2.4231 3.9806 2.2827 +2.4481 3.9677 2.2838 +2.4775 3.9608 2.2937 +2.5 3.9506 2.2907 +2.584 3.8692 2.1711 +2.6552 3.802 2.0235 +2.7198 3.7419 1.8592 +2.7842 3.6822 1.6896 +2.8545 3.6158 1.5262 +2.9369 3.5358 1.3803 +2.9441 3.5138 1.3448 +2.9406 3.4896 1.3055 +2.9496 3.4656 1.2729 +2.9678 3.4626 1.2743 +2.9922 3.4662 1.2879 +3.0115 3.462 1.2912 +3.085 3.3885 1.2749 +3.1699 3.3037 1.3014 +3.2593 3.2144 1.3429 +3.3466 3.1271 1.3715 +2.8027 5.8442 0.5494 +2.8024 5.8462 0.5103 +2.7816 5.8351 0.5422 +2.7786 5.8047 0.5757 +2.8075 5.8171 0.5854 +2.8443 5.6082 0.8053 +2.8109 5.5925 0.7953 +2.8386 5.4063 1.0407 +2.8766 5.4253 1.0506 +2.8818 5.3959 1.0753 +2.852 5.3809 1.0676 +2.8654 5.356 1.0951 +2.8869 5.367 1.1003 +2.8879 5.3609 1.1304 +2.8593 5.3462 1.1235 +2.8506 5.3381 1.153 +2.8885 5.3577 1.162 +2.9001 5.2921 1.3217 +2.8491 5.2657 1.3097 +2.8636 5.1871 1.4628 +2.914 5.2133 1.4745 +2.9287 5.1296 1.624 +2.8825 5.1055 1.6135 +2.8991 5.0843 1.6322 +2.9335 5.1022 1.6401 +2.9383 5.075 1.6564 +2.9155 5.0632 1.6511 +2.9045 5.0543 1.6869 +2.9389 5.0721 1.695 +2.9394 5.0691 1.7336 +2.8934 5.0454 1.7227 +2.9132 4.9104 1.9571 +2.9629 4.9356 1.9696 +2.988 4.7936 2.1992 +2.9345 4.767 2.185 +2.9532 4.7428 2.2009 +2.9934 4.7627 2.2116 +2.9989 4.7317 2.2239 +2.9721 4.7184 2.2167 +2.9589 4.7099 2.2475 +2.9994 4.7286 2.2599 +3.0003 4.7237 2.293 +2.9458 4.6999 2.275 +2.9622 4.5931 2.3385 +3.02 4.6117 2.3611 +3.0439 4.4766 2.38 +2.9816 4.4644 2.3541 +3.0032 4.3283 2.3289 +3.0692 4.3329 2.3549 +3.0718 4.3182 2.3258 +3.0221 4.3152 2.3063 +3.0411 4.3023 2.2827 +3.0743 4.3039 2.2955 +3.0794 4.275 2.299 +3.0373 4.2745 2.2838 +3.0261 4.2465 2.2937 +3.0845 4.246 2.3137 +3.089 4.2204 2.3125 +3.0216 4.2221 2.2907 +3.0401 4.1067 2.1711 +3.1093 4.1052 2.1921 +3.1265 4.0079 2.0443 +3.0543 4.0098 2.0235 +3.0664 3.9224 1.8592 +3.1421 3.9195 1.8803 +3.1576 3.8313 1.7115 +3.0785 3.8354 1.6896 +3.0926 3.7397 1.5262 +3.1747 3.7344 1.549 +3.1949 3.6198 1.4041 +3.1108 3.6264 1.3803 +3.1246 3.6078 1.3448 +3.198 3.6026 1.3664 +3.1995 3.5937 1.322 +3.1465 3.5967 1.3055 +3.161 3.5756 1.2729 +3.203 3.5741 1.2868 +3.2057 3.5587 1.2927 +3.1531 3.559 1.2743 +3.1361 3.5411 1.2879 +3.2084 3.5433 1.3149 +3.2113 3.5272 1.3228 +3.1285 3.5229 1.2912 +3.1465 3.4205 1.2749 +3.2287 3.4285 1.305 +3.2489 3.3136 1.3325 +3.1672 3.3024 1.3014 +3.1891 3.1779 1.3429 +3.2704 3.192 1.3758 +3.2913 3.0732 1.4055 +3.2106 3.0563 1.3715 +3.2929 3.0643 1.2905 +2.7745 5.8208 0.5247 +2.7691 5.7851 0.552 +2.8003 5.5665 0.7708 +2.8269 5.3741 1.0161 +2.8428 5.3552 1.0488 +2.8588 5.3371 1.082 +2.8505 5.3209 1.1064 +2.8391 5.3044 1.1307 +2.8337 5.2201 1.2803 +2.8483 5.1417 1.4342 +2.8686 5.0635 1.5876 +2.8887 5.0532 1.6128 +2.9085 5.0426 1.638 +2.894 5.0235 1.667 +2.8794 5.0043 1.6959 +2.8979 4.8673 1.9263 +2.918 4.722 2.1501 +2.9408 4.709 2.1746 +2.9637 4.6959 2.199 +2.9458 4.6798 2.2162 +2.9279 4.662 2.2309 +2.9409 4.5694 2.2825 +2.9559 4.4578 2.2909 +2.9735 4.3401 2.2658 +2.9996 4.3248 2.2591 +3.0259 4.3098 2.2516 +3.0173 4.2885 2.247 +2.9977 4.2685 2.2451 +2.9885 4.2497 2.237 +3.006 4.1347 2.1197 +3.0187 4.0399 1.9723 +3.0288 3.9557 1.8069 +3.0389 3.8726 1.6354 +3.0511 3.781 1.4697 +3.0679 3.6713 1.3218 +3.0875 3.6457 1.2919 +3.1199 3.6226 1.2654 +3.1403 3.5937 1.2391 +3.128 3.5762 1.2278 +3.1024 3.5602 1.2214 +3.0904 3.5412 1.2145 +3.1099 3.4302 1.2011 +3.1321 3.3046 1.2254 +3.1553 3.173 1.2631 +3.178 3.0439 1.2893 +2.786 5.8098 0.5072 +2.7848 5.77 0.5282 +2.8192 5.5457 0.7464 +2.849 5.3478 0.9916 +2.8602 5.3343 1.0299 +2.8714 5.3216 1.069 +2.8674 5.3 1.0894 +2.8614 5.2767 1.1084 +2.8638 5.1826 1.2508 +2.8782 5.1043 1.4055 +2.896 5.029 1.5618 +2.9091 5.0275 1.5934 +2.9221 5.0256 1.6249 +2.9144 4.9982 1.6471 +2.9066 4.9705 1.6691 +2.927 4.832 1.8954 +2.9489 4.6853 2.1151 +2.964 4.6815 2.1482 +2.9792 4.6776 2.1813 +2.9684 4.656 2.1851 +2.9577 4.6326 2.187 +2.9691 4.5547 2.227 +2.9823 4.4604 2.2282 +2.9974 4.3613 2.2028 +3.0175 4.3415 2.2119 +3.0376 4.3221 2.2206 +3.0313 4.3087 2.2102 +3.0168 4.2989 2.1962 +3.0101 4.287 2.1832 +3.0284 4.1725 2.0686 +3.0419 4.0799 1.9219 +3.0529 3.9991 1.7556 +3.0635 3.9202 1.5823 +3.0761 3.8331 1.4142 +3.093 3.7278 1.2639 +3.1095 3.6939 1.2393 +3.1361 3.6559 1.2254 +3.1535 3.6177 1.2052 +3.1457 3.6009 1.1817 +3.1276 3.5894 1.1557 +3.12 3.5711 1.1387 +3.1409 3.4525 1.1261 +3.1643 3.3193 1.1483 +3.1888 3.1801 1.1829 +3.2128 3.0435 1.2071 +2.809 5.8085 0.5 +2.8161 5.7682 0.5185 +2.8559 5.5424 0.7364 +2.8911 5.343 0.9816 +2.8933 5.3304 1.0223 +2.8954 5.3187 1.0638 +2.8994 5.296 1.0825 +2.9037 5.2713 1.0994 +2.9206 5.1754 1.2389 +2.9345 5.097 1.3939 +2.9477 5.0221 1.5513 +2.9476 5.0224 1.5856 +2.9476 5.0223 1.6196 +2.9528 4.9932 1.639 +2.9579 4.9639 1.6582 +2.9824 4.8253 1.8828 +3.0082 4.6786 2.1009 +3.0086 4.6765 2.1375 +3.009 4.6743 2.1741 +3.0129 4.6523 2.1727 +3.017 4.6289 2.1691 +3.0297 4.557 2.2046 +3.045 4.4703 2.2025 +3.061 4.3795 2.1768 +3.0652 4.3556 2.1925 +3.0694 4.332 2.2077 +3.071 4.3229 2.195 +3.0716 4.3192 2.176 +3.0729 4.3117 2.1613 +3.0931 4.1973 2.048 +3.1092 4.1059 1.9017 +3.1231 4.0271 1.7351 +3.1366 3.9506 1.5609 +3.1515 3.8658 1.3918 +3.1698 3.7625 1.2404 +3.1766 3.7237 1.2178 +3.1849 3.6768 1.2089 +3.1925 3.6334 1.1913 +3.1951 3.6191 1.1634 +3.1963 3.6118 1.1291 +3.1993 3.5952 1.1076 +3.2207 3.4736 1.0954 +3.2448 3.3372 1.1166 +3.2699 3.1948 1.1497 +3.2945 3.0552 1.1731 +2.8302 5.8176 0.5072 +2.8449 5.7806 0.5282 +2.8893 5.5581 0.7464 +2.929 5.362 0.9916 +2.9231 5.3454 1.0299 +2.9169 5.3297 1.069 +2.928 5.3107 1.0894 +2.9416 5.2908 1.1084 +2.9716 5.2016 1.2508 +2.9848 5.1231 1.4055 +2.9939 5.0462 1.5618 +2.982 5.0403 1.5934 +2.9705 5.0342 1.6249 +2.9871 5.011 1.6471 +3.0039 4.9876 1.6691 +3.0321 4.8505 1.8954 +3.0617 4.7052 2.1151 +3.0488 4.6964 2.1482 +3.0358 4.6876 2.1813 +3.0534 4.671 2.1851 +3.0714 4.6527 2.187 +3.0874 4.5756 2.227 +3.1073 4.4824 2.2282 +3.1269 4.3841 2.2028 +3.1148 4.3587 2.2119 +3.1025 4.3336 2.2206 +3.1131 4.3232 2.2102 +3.13 4.3189 2.1962 +3.1404 4.3099 2.1832 +3.1624 4.1961 2.0686 +3.1814 4.1044 1.9219 +3.1987 4.0248 1.7556 +3.2157 3.947 1.5823 +3.2336 3.8609 1.4142 +3.2538 3.7562 1.2639 +3.2499 3.7186 1.2393 +3.2379 3.6739 1.2254 +3.2346 3.6319 1.2052 +3.2477 3.6188 1.1817 +3.2686 3.6142 1.1557 +3.282 3.5997 1.1387 +3.3029 3.4811 1.1261 +3.3265 3.3479 1.1483 +3.3511 3.2087 1.1829 +3.3752 3.0721 1.2071 +2.8372 5.8319 0.5247 +2.8545 5.8002 0.552 +2.8999 5.584 0.7708 +2.9408 5.3942 1.0161 +2.9323 5.371 1.0488 +2.9234 5.3485 1.082 +2.9368 5.3361 1.1064 +2.9532 5.3245 1.1307 +2.9871 5.2472 1.2803 +3.0001 5.1685 1.4342 +3.0078 5.0881 1.5876 +2.9924 5.0715 1.6128 +2.9774 5.0547 1.638 +2.9976 5.0418 1.667 +3.0179 5.0287 1.6959 +3.0474 4.8937 1.9263 +3.0782 4.7502 2.1501 +3.0613 4.7302 2.1746 +3.0441 4.7101 2.199 +3.0665 4.7011 2.2162 +3.0894 4.6905 2.2309 +3.1088 4.599 2.2825 +3.1329 4.489 2.2909 +3.1567 4.3724 2.2658 +3.1374 4.349 2.2591 +3.1178 4.326 2.2516 +3.1332 4.3089 2.247 +3.1584 4.2969 2.2451 +3.1735 4.2823 2.237 +3.1964 4.1682 2.1197 +3.2169 4.0748 1.9723 +3.2361 3.9922 1.8069 +3.2551 3.9107 1.6354 +3.275 3.8205 1.4697 +3.2966 3.7117 1.3218 +3.287 3.6809 1.2919 +3.2645 3.6481 1.2654 +3.2552 3.6139 1.2391 +3.2727 3.6017 1.2278 +3.3023 3.5955 1.2214 +3.3201 3.5817 1.2145 +3.3397 3.4707 1.2011 +3.3618 3.3451 1.2254 +3.385 3.2135 1.2631 +3.4078 3.0845 1.2893 +2.8257 5.8429 0.5422 +2.8388 5.8153 0.5757 +2.8811 5.6049 0.7953 +2.9187 5.4205 1.0407 +2.9149 5.392 1.0676 +2.9108 5.364 1.0951 +2.9199 5.3569 1.1235 +2.9308 5.3523 1.153 +2.9569 5.2847 1.3097 +2.9702 5.2059 1.4628 +2.9804 5.1227 1.6135 +2.972 5.0972 1.6322 +2.9639 5.0717 1.6511 +2.9772 5.0672 1.6869 +2.9907 5.0625 1.7227 +3.0183 4.929 1.9571 +3.0473 4.7869 2.185 +3.038 4.7577 2.2009 +3.0286 4.7284 2.2167 +3.0439 4.7249 2.2475 +3.0596 4.7199 2.275 +3.0807 4.6139 2.3385 +3.1065 4.4865 2.3541 +3.1327 4.3511 2.3289 +3.1195 4.3323 2.3063 +3.106 4.3137 2.2827 +3.1191 4.2889 2.2838 +3.1392 4.2664 2.2937 +3.1518 4.2451 2.2907 +3.1739 4.1303 2.1711 +3.1937 4.0343 2.0235 +3.2122 3.9481 1.8592 +3.2306 3.8622 1.6896 +3.2501 3.7675 1.5262 +3.2718 3.6547 1.3803 +3.2651 3.6325 1.3448 +3.2483 3.6147 1.3055 +3.242 3.5899 1.2729 +3.2551 3.577 1.2743 +3.2772 3.566 1.2879 +3.2906 3.5514 1.2912 +3.3086 3.4491 1.2749 +3.3295 3.331 1.3014 +3.3515 3.2066 1.3429 +3.373 3.0849 1.3715 +4.3656 6.0115 0.5494 +4.3664 6.0137 0.5103 +4.3425 6.0137 0.5422 +4.3236 5.9858 0.5756 +4.3552 5.9829 0.5854 +4.2746 5.7613 0.8053 +4.2373 5.7634 0.7952 +4.1609 5.5687 1.0405 +4.204 5.5675 1.0506 +4.1927 5.5363 1.0753 +4.1588 5.5371 1.0675 +4.157 5.506 1.095 +4.1815 5.5056 1.1003 +4.1792 5.4992 1.1304 +4.1464 5.4997 1.1234 +4.1345 5.4964 1.1529 +4.1779 5.4957 1.162 +4.1526 5.4262 1.3217 +4.0943 5.4269 1.3095 +4.0644 5.3432 1.4626 +4.1222 5.3427 1.4745 +4.0899 5.2539 1.624 +4.0368 5.2543 1.6133 +4.0399 5.2253 1.6321 +4.0794 5.225 1.6401 +4.0689 5.1961 1.6564 +4.0426 5.1964 1.651 +4.0283 5.1935 1.6868 +4.0677 5.193 1.695 +4.0666 5.1899 1.7336 +4.0139 5.1905 1.7225 +3.9584 5.0495 1.9569 +4.0151 5.0483 1.9696 +3.9602 4.8977 2.1992 +3.8997 4.8995 2.1848 +3.9028 4.8664 2.2008 +3.9483 4.865 2.2116 +3.9364 4.8321 2.2239 +3.906 4.833 2.2166 +3.8901 4.8316 2.2473 +3.9352 4.8288 2.2599 +3.9333 4.8236 2.293 +3.8734 4.8287 2.2748 +3.8302 4.7167 2.3383 +3.8901 4.7049 2.3611 +3.8379 4.5616 2.38 +3.7778 4.5821 2.354 +3.7233 4.439 2.3288 +3.7825 4.4093 2.3549 +3.7768 4.3937 2.3258 +3.7325 4.4165 2.3063 +3.7419 4.3942 2.2827 +3.7713 4.3785 2.2955 +3.7601 4.3479 2.299 +3.7236 4.3692 2.2837 +3.6989 4.348 2.2936 +3.7489 4.3171 2.3137 +3.7391 4.2901 2.3125 +3.6819 4.3268 2.2905 +3.6357 4.2053 2.1709 +3.6946 4.1679 2.1921 +3.6571 4.0647 2.0443 +3.5959 4.1041 2.0233 +3.5593 4.0132 1.859 +3.623 3.971 1.8803 +3.5889 3.8775 1.7115 +3.5229 3.9227 1.6894 +3.4835 3.8228 1.5259 +3.5515 3.7747 1.549 +3.5073 3.6532 1.4041 +3.4383 3.7036 1.38 +3.4402 3.6783 1.3446 +3.5007 3.6351 1.3664 +3.4972 3.6256 1.322 +3.4531 3.6562 1.3053 +3.4543 3.6281 1.2729 +3.4897 3.6048 1.2868 +3.4837 3.5885 1.2927 +3.4385 3.6161 1.2742 +3.4143 3.6075 1.2878 +3.4778 3.5722 1.3149 +3.4716 3.555 1.3228 +3.398 3.5938 1.2912 +3.3585 3.4853 1.2748 +3.4335 3.4504 1.305 +3.3892 3.3287 1.3325 +3.3129 3.3601 1.3013 +3.2648 3.2282 1.3428 +3.3422 3.1997 1.3758 +3.2964 3.0738 1.4055 +3.2179 3.0992 1.3715 +4.3289 6.0035 0.5247 +4.305 5.9718 0.552 +4.2143 5.7438 0.7708 +4.1338 5.5436 1.0161 +4.1373 5.5171 1.0488 +4.1414 5.4912 1.082 +4.1255 5.4798 1.1064 +4.1068 5.4698 1.1307 +4.0569 5.3909 1.2803 +4.0273 5.3073 1.4342 +4.0027 5.2211 1.5876 +4.0145 5.2006 1.6128 +4.0258 5.1801 1.638 +4.0031 5.1692 1.667 +3.9802 5.1581 1.6959 +3.9225 5.0158 1.9263 +3.8616 4.8646 2.1501 +3.8742 4.8402 2.1746 +3.8869 4.8156 2.199 +3.8628 4.8093 2.2162 +3.8379 4.8013 2.2309 +3.7994 4.7049 2.2825 +3.7522 4.589 2.2909 +3.704 4.4658 2.2658 +3.7183 4.4375 2.2591 +3.7329 4.4094 2.2516 +3.714 4.3932 2.247 +3.6864 4.384 2.2451 +3.6684 4.3705 2.237 +3.6216 4.25 2.1197 +3.5816 4.1516 1.9723 +3.5451 4.0647 1.8069 +3.509 3.979 1.6354 +3.4703 3.884 1.4697 +3.4259 3.769 1.3218 +3.4289 3.734 1.2919 +3.4443 3.6948 1.2654 +3.4463 3.6562 1.2391 +3.4264 3.6457 1.2278 +3.3957 3.6435 1.2214 +3.3752 3.6312 1.2145 +3.3323 3.5136 1.2011 +3.2839 3.3804 1.2254 +3.2331 3.2409 1.2631 +3.1833 3.1041 1.2893 +4.3328 5.987 0.5073 +4.3103 5.9491 0.5283 +4.2193 5.714 0.7465 +4.1385 5.507 0.9917 +4.1409 5.488 1.03 +4.1438 5.4699 1.0691 +4.1287 5.451 1.0895 +4.111 5.4316 1.1086 +4.0624 5.3394 1.251 +4.0327 5.2561 1.4057 +4.0075 5.1738 1.5619 +4.0181 5.1654 1.5936 +4.0282 5.1568 1.625 +4.0068 5.1343 1.6472 +3.9852 5.1116 1.6693 +3.9283 4.9669 1.8955 +3.8683 4.8134 2.1153 +3.8793 4.8017 2.1484 +3.8903 4.7901 2.1814 +3.8694 4.7747 2.1852 +3.8476 4.7576 2.1872 +3.8155 4.6762 2.2272 +3.7762 4.5779 2.2283 +3.736 4.4739 2.2029 +3.7426 4.4444 2.212 +3.7495 4.4152 2.2206 +3.7368 4.4055 2.2102 +3.7191 4.4035 2.1963 +3.7069 4.3954 2.1834 +3.661 4.2749 2.0688 +3.6228 4.1782 1.9221 +3.5888 4.0943 1.7558 +3.5555 4.0123 1.5825 +3.5195 3.9214 1.4144 +3.4773 3.8106 1.2642 +3.4734 3.7692 1.2395 +3.4759 3.7187 1.2255 +3.4705 3.6726 1.2053 +3.4547 3.6604 1.1818 +3.433 3.6587 1.1558 +3.4167 3.6449 1.1388 +3.3709 3.5192 1.1261 +3.3194 3.378 1.1484 +3.2657 3.2304 1.1829 +3.2129 3.0857 1.2071 +4.3519 5.9737 0.5 +4.3363 5.931 0.5185 +4.2492 5.6916 0.7364 +4.1723 5.4802 0.9816 +4.1674 5.4668 1.0223 +4.1629 5.4544 1.0638 +4.1541 5.4304 1.0825 +4.1446 5.4042 1.0994 +4.1076 5.3025 1.2389 +4.0773 5.2194 1.3939 +4.0484 5.14 1.5513 +4.0485 5.1403 1.5856 +4.0485 5.1402 1.6196 +4.0373 5.1094 1.639 +4.026 5.0783 1.6582 +3.9725 4.9314 1.8828 +3.9159 4.7758 2.1009 +3.9151 4.7736 2.1375 +3.9142 4.7713 2.1741 +3.9057 4.7479 2.1727 +3.8967 4.7231 2.1691 +3.869 4.6469 2.2046 +3.8355 4.555 2.2025 +3.8004 4.4587 2.1768 +3.7912 4.4334 2.1925 +3.7821 4.4083 2.2077 +3.7786 4.3987 2.195 +3.7772 4.3948 2.176 +3.7743 4.3868 2.1613 +3.7301 4.2655 2.048 +3.6949 4.1686 1.9017 +3.6645 4.0851 1.7351 +3.6349 4.004 1.5609 +3.6022 3.9141 1.3918 +3.5624 3.8046 1.2404 +3.5474 3.7634 1.2178 +3.5293 3.7137 1.2089 +3.5126 3.6677 1.1913 +3.507 3.6525 1.1634 +3.5042 3.6448 1.1291 +3.4978 3.6272 1.1076 +3.4509 3.4982 1.0954 +3.3982 3.3536 1.1166 +3.3433 3.2027 1.1497 +3.2894 3.0546 1.1731 +4.375 5.9716 0.5073 +4.3679 5.9281 0.5283 +4.2865 5.6895 0.7465 +4.2153 5.479 0.9917 +4.2013 5.466 1.03 +4.1874 5.454 1.0691 +4.1869 5.4299 1.0895 +4.188 5.4036 1.1086 +4.1659 5.3017 1.251 +4.1351 5.2188 1.4057 +4.1015 5.1396 1.5619 +4.088 5.14 1.5936 +4.0747 5.1399 1.625 +4.0767 5.1089 1.6472 +4.0786 5.0776 1.6693 +4.0292 4.9302 1.8955 +3.9765 4.774 2.1153 +3.9606 4.7722 2.1484 +3.9446 4.7703 2.1814 +3.9508 4.7451 2.1852 +3.9565 4.718 2.1872 +3.9287 4.635 2.2272 +3.8957 4.5344 2.2283 +3.8596 4.429 2.2029 +3.8356 4.4106 2.212 +3.8115 4.3926 2.2206 +3.815 4.3771 2.2102 +3.8273 4.3641 2.1963 +3.8314 4.35 2.1834 +3.7892 4.2283 2.0688 +3.7563 4.1296 1.9221 +3.7284 4.0435 1.7558 +3.7012 3.9593 1.5825 +3.6703 3.8665 1.4144 +3.6314 3.7545 1.2642 +3.6078 3.7203 1.2395 +3.5734 3.6832 1.2255 +3.548 3.6444 1.2053 +3.5522 3.6249 1.1818 +3.5677 3.6097 1.1558 +3.5713 3.5886 1.1388 +3.5256 3.4628 1.1261 +3.4743 3.3217 1.1484 +3.4206 3.174 1.1829 +3.3679 3.0292 1.2071 +4.3887 5.9818 0.5247 +4.3865 5.9421 0.552 +4.3094 5.7092 0.7708 +4.2424 5.5041 1.0161 +4.2227 5.486 1.0488 +4.203 5.4688 1.082 +4.2078 5.4498 1.1064 +4.2157 5.4302 1.1307 +4.2032 5.3376 1.2803 +4.1721 5.2546 1.4342 +4.1356 5.1727 1.5876 +4.1134 5.1646 1.6128 +4.0916 5.1562 1.638 +4.1019 5.1332 1.667 +4.1123 5.11 1.6959 +4.0651 4.9639 1.9263 +4.0145 4.8089 2.1501 +3.9892 4.7984 2.1746 +3.9637 4.7877 2.199 +3.978 4.7674 2.2162 +3.992 4.7453 2.2309 +3.9596 4.6466 2.2825 +3.9211 4.5275 2.2909 +3.8789 4.4022 2.2658 +3.8497 4.3896 2.2591 +3.8205 4.3775 2.2516 +3.8246 4.3529 2.247 +3.8398 4.3282 2.2451 +3.845 4.3062 2.237 +3.8033 4.1839 2.1197 +3.7707 4.0827 1.9723 +3.7429 3.9928 1.8069 +3.7154 3.9039 1.6354 +3.6839 3.8062 1.4697 +3.6441 3.6896 1.3218 +3.6193 3.6647 1.2919 +3.5823 3.6446 1.2654 +3.5559 3.6163 1.2391 +3.5644 3.5955 1.2278 +3.5865 3.574 1.2214 +3.5944 3.5515 1.2145 +3.5516 3.4338 1.2011 +3.5031 3.3006 1.2254 +3.4523 3.1611 1.2631 +3.4025 3.0243 1.2893 +4.3848 5.9983 0.5422 +4.3813 5.9648 0.5756 +4.3045 5.7389 0.7952 +4.2378 5.5407 1.0405 +4.2192 5.5151 1.0675 +4.2006 5.4902 1.095 +4.2046 5.4785 1.1234 +4.2115 5.4683 1.1529 +4.1977 5.3892 1.3095 +4.1668 5.306 1.4626 +4.1308 5.2201 1.6133 +4.1098 5.1998 1.6321 +4.0891 5.1795 1.651 +4.0982 5.168 1.6868 +4.1073 5.1565 1.7225 +4.0593 5.0128 1.9569 +4.0078 4.8602 2.1848 +3.9841 4.8368 2.2008 +3.9602 4.8133 2.2166 +3.9715 4.802 2.2473 +3.9824 4.789 2.2748 +3.9435 4.6755 2.3383 +3.8972 4.5386 2.354 +3.8469 4.394 2.3288 +3.8254 4.3827 2.3063 +3.8039 4.3716 2.2827 +3.8018 4.3408 2.2837 +3.8071 4.3086 2.2936 +3.8065 4.2815 2.2905 +3.7638 4.1587 2.1709 +3.7293 4.0556 2.0233 +3.6988 3.9624 1.859 +3.6686 3.8697 1.6894 +3.6345 3.7678 1.5259 +3.5925 3.6474 1.38 +3.5748 3.6293 1.3446 +3.5506 3.6207 1.3053 +3.5318 3.5999 1.2729 +3.5361 3.5806 1.2742 +3.5491 3.5585 1.2878 +3.5528 3.5375 1.2912 +3.5133 3.4289 1.2748 +3.4678 3.3037 1.3013 +3.4198 3.1718 1.3428 +3.3729 3.0427 1.3715 +2.8804 2.8279 1.1689 +2.8359 2.8634 1.1804 +2.8778 2.8398 1.1654 +2.9354 2.811 1.166 +2.9399 2.7906 1.1755 +3.0074 2.7589 1.1913 +3.0006 2.7874 1.1755 +3.0662 2.7748 1.1864 +3.0761 2.74 1.2074 +3.1388 2.7415 1.2147 +3.1253 2.7788 1.1913 +3.247 2.8173 1.1908 +3.261 2.7787 1.2147 +3.3786 2.8287 1.2147 +3.365 2.8661 1.1913 +3.4926 2.9277 1.1846 +3.5048 2.8948 1.2064 +3.6211 2.9678 1.1897 +3.611 2.9946 1.171 +3.7073 3.0653 1.1626 +3.7147 3.0457 1.1773 +3.7732 3.1263 1.1818 +3.7686 3.1384 1.1712 +3.7838 3.2073 1.2159 +3.802 3.1685 1.1978 +3.7979 3.1785 1.1864 +3.823 3.1441 1.1706 +3.8297 3.1275 1.1913 +3.8649 3.0888 1.1921 +3.8551 3.1125 1.1594 +3.8922 3.0873 1.1512 +3.9055 3.0569 1.1963 +3.9495 3.0364 1.1998 +3.9324 3.0718 1.1446 +3.9739 3.0697 1.1381 +3.9948 3.0317 1.1985 +4.0651 3.0398 1.1907 +4.0426 3.08 1.1267 +4.111 3.0927 1.1155 +4.135 3.0507 1.1824 +4.2437 3.0712 1.1676 +4.2183 3.1157 1.0966 +4.3252 3.1408 1.0783 +4.3519 3.0941 1.1527 +4.4449 3.1247 1.141 +4.4184 3.1719 1.0659 +4.5087 3.2137 1.0571 +4.5341 3.1677 1.13 +4.6213 3.217 1.1195 +4.5975 3.2609 1.0503 +4.6861 3.308 1.044 +4.7083 3.2665 1.1096 +4.8116 3.3297 1.0918 +4.7899 3.366 1.0335 +4.8856 3.4306 1.0215 +4.9041 3.4013 1.0677 +4.9805 3.4781 1.0454 +4.9669 3.4996 1.0137 +5.0274 3.5703 1.0157 +5.0355 3.5568 1.0332 +5.0639 3.6344 1.0392 +2.8134 2.8896 1.2191 +2.8331 2.8737 1.1813 +2.8743 2.8539 1.1627 +2.9299 2.8344 1.1578 +2.9925 2.8194 1.161 +3.0551 2.8131 1.1666 +3.1104 2.8196 1.1691 +3.2316 2.8597 1.1681 +3.3502 2.9069 1.1691 +3.4792 2.9639 1.1643 +3.6 3.0243 1.1541 +3.6993 3.0872 1.1495 +3.7636 3.1518 1.1615 +3.7754 3.2274 1.1933 +3.7936 3.1893 1.1757 +3.8159 3.1622 1.151 +3.8446 3.1385 1.1282 +3.8779 3.1207 1.1083 +3.9143 3.111 1.0922 +3.9519 3.1117 1.0808 +4.019 3.1243 1.0659 +4.0859 3.1391 1.0519 +4.1917 3.1648 1.0293 +4.2973 3.1923 1.0077 +4.3906 3.2241 0.9946 +4.482 3.2645 0.9879 +4.5724 3.3092 0.9846 +4.6628 3.3538 0.9817 +4.7671 3.4061 0.978 +4.8663 3.4631 0.9776 +4.9527 3.5232 0.9836 +5.0188 3.585 0.9992 +5.0572 3.647 1.0275 +5.0604 3.7075 1.0717 +2.8288 2.8869 1.1815 +2.8709 2.8662 1.1575 +2.9245 2.8543 1.1488 +2.985 2.8463 1.1487 +3.0452 2.8451 1.1519 +3.098 2.8538 1.1535 +3.2188 2.8948 1.1524 +3.3377 2.9411 1.1535 +3.469 2.9987 1.1482 +3.5899 3.0598 1.1367 +3.6891 3.12 1.1322 +3.7556 3.1747 1.1475 +3.7881 3.2023 1.163 +3.8072 3.1824 1.1308 +3.833 3.1645 1.101 +3.8638 3.1511 1.0752 +3.8982 3.1445 1.0546 +3.9343 3.1471 1.0408 +4.0001 3.1618 1.0235 +4.0658 3.1782 1.0075 +4.1705 3.2063 0.9822 +4.2751 3.2357 0.9583 +4.3684 3.268 0.9447 +4.4607 3.3073 0.9395 +4.5524 3.3499 0.9387 +4.6441 3.3924 0.9382 +4.7498 3.4432 0.937 +4.8502 3.4986 0.9402 +4.9383 3.5556 0.9514 +5.0073 3.6113 0.9745 +5.0503 3.6629 1.0133 +2.8658 2.883 1.1589 +2.9169 2.88 1.1475 +2.975 2.8797 1.1438 +3.0328 2.884 1.1439 +3.083 2.8949 1.1441 +3.2033 2.9373 1.1431 +3.3227 2.9822 1.1441 +3.4569 3.0388 1.1381 +3.5786 3.0981 1.1255 +3.6785 3.1535 1.121 +3.7472 3.1988 1.1388 +3.7819 3.2183 1.1557 +3.7973 3.2072 1.119 +3.8201 3.1965 1.0849 +3.8485 3.1886 1.0553 +3.8809 3.1858 1.0319 +3.9156 3.1906 1.0166 +3.9802 3.2079 0.9978 +4.0448 3.2264 0.9806 +4.1482 3.2574 0.9537 +4.2517 3.2894 0.9285 +4.3449 3.3222 0.9146 +4.438 3.3599 0.9103 +4.531 3.3999 0.9109 +4.624 3.4397 0.9118 +4.7311 3.4887 0.9124 +4.8327 3.542 0.918 +4.9226 3.5951 0.9327 +4.9946 3.6434 0.9605 +5.0426 3.6824 1.0055 +2.8228 2.903 1.1805 +2.8576 2.9081 1.16 +2.9016 2.9265 1.1478 +2.9524 2.9473 1.1428 +3.0038 2.9679 1.142 +3.05 2.9855 1.142 +3.1699 3.0292 1.1413 +3.2898 3.0728 1.142 +3.4269 3.1216 1.1361 +3.5542 3.1657 1.1245 +3.6611 3.202 1.1209 +3.7369 3.2276 1.1391 +3.7709 3.2395 1.1926 +3.7738 3.241 1.1555 +3.7838 3.2462 1.118 +3.8001 3.2543 1.0825 +3.8221 3.2645 1.0513 +3.8488 3.2761 1.0267 +3.8795 3.2882 1.0111 +3.9418 3.3115 0.992 +4.0045 3.3349 0.9746 +4.1055 3.3723 0.9473 +4.2069 3.4098 0.9218 +4.2999 3.4438 0.9078 +4.3944 3.4778 0.9038 +4.4896 3.5118 0.9048 +4.5848 3.5458 0.9059 +4.695 3.5846 0.9071 +4.8026 3.6214 0.914 +4.9001 3.6541 0.9303 +4.9805 3.6807 0.9596 +5.0363 3.6992 1.0055 +2.8468 2.9334 1.1576 +2.8818 2.9737 1.1464 +2.924 3.0165 1.143 +2.9697 3.0546 1.1434 +3.0153 3.0808 1.1437 +3.1345 3.1264 1.1425 +3.2551 3.1681 1.1437 +3.3961 3.2081 1.1375 +3.5295 3.2354 1.1245 +3.6434 3.2512 1.1195 +3.7263 3.2564 1.1374 +3.7663 3.2522 1.1932 +3.7649 3.264 1.1544 +3.768 3.2857 1.1172 +3.7764 3.3132 1.0833 +3.791 3.3426 1.054 +3.8127 3.3699 1.0309 +3.8425 3.3913 1.0155 +3.9025 3.4209 0.9967 +3.9634 3.4495 0.9794 +4.062 3.4938 0.9524 +4.1613 3.5372 0.9271 +4.2537 3.5722 0.9132 +4.3496 3.6024 0.9089 +4.4471 3.6301 0.9096 +4.5445 3.6578 0.9106 +4.6602 3.6863 0.9111 +4.7746 3.7051 0.9164 +4.8798 3.7154 0.9307 +4.9678 3.7184 0.9584 +5.0306 3.7154 1.004 +2.817 2.9169 1.1797 +2.8392 2.9509 1.1555 +2.8701 2.9999 1.1469 +2.909 3.0503 1.1473 +2.9531 3.0943 1.151 +2.9995 3.1243 1.1527 +3.1181 3.1713 1.1515 +3.2393 3.2115 1.1527 +3.3782 3.2487 1.1473 +3.5119 3.2743 1.1354 +3.6286 3.2864 1.1304 +3.7163 3.2824 1.1459 +3.7629 3.2629 1.2011 +3.7587 3.282 1.1613 +3.7584 3.3134 1.1285 +3.7642 3.3483 1.0988 +3.7771 3.3834 1.0733 +3.798 3.4148 1.0529 +3.8278 3.4391 1.0388 +3.887 3.4717 1.0214 +3.9475 3.5027 1.0053 +4.045 3.5502 0.9798 +4.1435 3.5963 0.9559 +4.2356 3.6319 0.9422 +4.3319 3.6602 0.9371 +4.4302 3.685 0.9363 +4.5283 3.7097 0.936 +4.6439 3.7357 0.935 +4.7584 3.7527 0.9379 +4.8646 3.7595 0.949 +4.9552 3.755 0.9723 +5.0229 3.7381 1.0118 +2.8335 2.9631 1.1607 +2.8607 3.0192 1.156 +2.8966 3.0766 1.1598 +2.9393 3.1264 1.166 +2.9865 3.16 1.1686 +3.1047 3.2082 1.1676 +3.2263 3.2472 1.1686 +3.3625 3.2832 1.1639 +3.4954 3.3099 1.1534 +3.6139 3.3202 1.1485 +3.7068 3.3069 1.1607 +3.754 3.2969 1.1745 +3.7512 3.3362 1.1495 +3.7554 3.3774 1.127 +3.7673 3.4173 1.1074 +3.7879 3.4523 1.0915 +3.818 3.4792 1.0798 +3.8768 3.5143 1.0648 +3.9371 3.5474 1.0507 +4.034 3.5975 1.028 +4.132 3.646 1.0064 +4.2237 3.6819 0.9932 +4.3201 3.7087 0.9865 +4.4188 3.7309 0.9832 +4.5173 3.7531 0.9805 +4.6323 3.7771 0.977 +4.7467 3.7926 0.9767 +4.8535 3.7965 0.9828 +4.946 3.7856 0.9984 +5.0172 3.757 1.027 +2.8121 2.9277 1.1791 +2.8266 2.977 1.1636 +2.8495 3.0413 1.1648 +2.882 3.1065 1.1751 +2.923 3.1629 1.1868 +2.9717 3.2008 1.192 +3.0893 3.2505 1.1915 +3.2114 3.2881 1.192 +3.3496 3.3197 1.1853 +3.4848 3.3402 1.1716 +3.6059 3.3429 1.1631 +3.7018 3.3211 1.1715 +3.7598 3.2734 1.2165 +3.7503 3.3084 1.1862 +3.7449 3.3551 1.1707 +3.7466 3.4045 1.1601 +3.7567 3.4521 1.1527 +3.7768 3.4939 1.1466 +3.8082 3.5256 1.14 +3.8668 3.5636 1.1287 +3.9269 3.5992 1.1176 +4.0232 3.6524 1.0988 +4.1207 3.7035 1.0807 +4.2119 3.7399 1.0682 +4.3083 3.765 1.0593 +4.4072 3.7843 1.0524 +4.5061 3.8032 1.046 +4.6244 3.8226 1.0354 +4.741 3.8302 1.023 +4.8494 3.8243 1.0148 +4.943 3.8031 1.0163 +5.0141 3.7719 1.0403 +2.8209 2.9878 1.1675 +2.8397 3.0595 1.1749 +2.8688 3.1321 1.1919 +2.9084 3.1948 1.209 +2.9584 3.2372 1.2168 +3.0756 3.2882 1.2168 +3.1982 3.3244 1.2168 +3.3382 3.3521 1.2086 +3.4756 3.3669 1.192 +3.5991 3.3628 1.1796 +3.6975 3.3337 1.1837 +3.7469 3.3189 1.1987 +3.7393 3.3723 1.193 +3.739 3.4287 1.1951 +3.7477 3.4833 1.2005 +3.7676 3.5312 1.2049 +3.8005 3.5673 1.2039 +3.859 3.6079 1.1964 +3.9192 3.6458 1.1884 +4.015 3.7018 1.174 +4.1121 3.7553 1.1594 +4.2028 3.7921 1.1478 +4.299 3.8156 1.1365 +4.3981 3.8322 1.1258 +4.4971 3.8483 1.1155 +4.6185 3.8634 1.0972 +4.7369 3.864 1.0721 +4.8463 3.8494 1.0488 +4.9407 3.8189 1.0354 +2.8042 2.9453 1.1815 +2.8103 3.009 1.1759 +2.8238 3.0896 1.1937 +2.8492 3.1697 1.2215 +2.8876 3.2389 1.2475 +2.9404 3.2866 1.2598 +3.0569 3.3395 1.261 +3.1802 3.3738 1.2598 +3.3237 3.3963 1.2476 +3.4638 3.404 1.2251 +3.59 3.391 1.206 +3.6918 3.3515 1.2034 +3.758 3.2802 1.2303 +3.7408 3.3366 1.2191 +3.7289 3.3992 1.23 +3.7253 3.4637 1.2538 +3.7327 3.5256 1.2818 +3.7542 3.5808 1.3051 +3.7925 3.6247 1.3146 +3.8512 3.6689 1.3138 +3.9118 3.7102 1.3113 +4.0069 3.7701 1.3042 +4.1038 3.8269 1.2959 +4.1936 3.864 1.2858 +4.2895 3.8855 1.2708 +4.3885 3.8986 1.2535 +4.4875 3.9104 1.2359 +4.6179 3.9203 1.2016 +4.7392 3.913 1.1532 +4.8476 3.8883 1.1033 +4.9397 3.8459 1.0646 +5.0118 3.7857 1.0498 +2.8026 3.0225 1.1841 +2.8113 3.1104 1.2125 +2.833 3.1977 1.2518 +2.8703 3.2736 1.2875 +2.9258 3.3268 1.3047 +3.0418 3.3813 1.3072 +3.1656 3.4141 1.3047 +3.3124 3.4318 1.289 +3.4551 3.4333 1.2611 +3.5836 3.4131 1.2351 +3.6875 3.3658 1.225 +3.7567 3.2858 1.2446 +3.7354 3.3522 1.2404 +3.72 3.4223 1.2682 +3.7139 3.4929 1.3146 +3.7209 3.5604 1.366 +3.7446 3.6214 1.4091 +3.7887 3.6726 1.4304 +3.8478 3.7195 1.4363 +3.909 3.7639 1.4398 +4.0038 3.8269 1.4404 +4.1007 3.8865 1.4387 +4.1896 3.9238 1.4299 +4.2849 3.9436 1.4109 +4.3836 3.9537 1.3866 +4.4822 3.962 1.3619 +4.6212 3.9674 1.3104 +4.7444 3.9539 1.2373 +4.851 3.9213 1.1598 +4.9399 3.8695 1.095 +5.01 3.7982 1.0599 +2.7927 2.9752 1.2259 +2.7884 3.0582 1.2527 +2.7978 3.1439 1.2837 +2.8215 3.2263 1.3147 +2.8609 3.2976 1.3423 +2.9166 3.3521 1.3601 +3.0311 3.4093 1.3663 +3.1563 3.4394 1.3601 +3.3028 3.4574 1.3418 +3.4449 3.4609 1.3124 +3.5742 3.4391 1.2825 +3.6819 3.3831 1.2626 +3.7563 3.2895 1.2623 +3.7313 3.3679 1.2812 +3.7136 3.4443 1.3333 +3.7071 3.5174 1.4036 +3.7158 3.5862 1.477 +3.7433 3.6492 1.5385 +3.7935 3.7053 1.573 +3.8537 3.7543 1.5871 +3.9161 3.8009 1.5979 +4.0111 3.8661 1.6082 +4.1086 3.9276 1.6144 +4.1967 3.965 1.6076 +4.2912 3.9838 1.5845 +4.3888 3.9919 1.5519 +4.4861 3.9971 1.5169 +4.6275 3.9995 1.4457 +4.7495 3.9851 1.3508 +4.853 3.9512 1.2489 +4.9388 3.8953 1.1572 +5.0076 3.8149 1.0924 +2.7922 2.9767 1.2497 +2.788 3.0586 1.2869 +2.7984 3.1401 1.3255 +2.8235 3.218 1.3626 +2.8637 3.2873 1.3946 +2.9196 3.3438 1.4168 +3.0329 3.4021 1.4257 +3.1594 3.4311 1.4168 +3.3053 3.4499 1.3974 +3.447 3.4557 1.3683 +3.5762 3.4367 1.3351 +3.6836 3.3827 1.3037 +3.7575 3.2887 1.2805 +3.7285 3.3783 1.3224 +3.709 3.4551 1.3982 +3.7033 3.5224 1.4917 +3.7156 3.5836 1.5871 +3.7503 3.6423 1.6683 +3.8119 3.7018 1.7192 +3.8738 3.7506 1.7418 +3.9384 3.7978 1.7602 +4.0343 3.8625 1.7802 +4.1333 3.9241 1.7947 +4.2206 3.9612 1.7898 +4.314 3.9803 1.7623 +4.4098 3.9885 1.7212 +4.5047 3.9928 1.6759 +4.6492 3.9972 1.5825 +4.7677 3.99 1.4645 +4.8642 3.9642 1.3381 +4.9425 3.9131 1.2197 +5.0065 3.8298 1.1255 +2.8043 2.9444 1.2837 +2.8042 3.0152 1.3385 +2.8151 3.0946 1.3842 +2.8388 3.175 1.4214 +2.8773 3.2489 1.4506 +2.9324 3.3087 1.4726 +3.0454 3.3666 1.4831 +3.1722 3.3959 1.4726 +3.318 3.4153 1.4511 +3.4604 3.4225 1.4204 +3.5887 3.4088 1.383 +3.6921 3.3656 1.3415 +3.76 3.2843 1.2983 +3.7313 3.3749 1.3621 +3.7138 3.4465 1.4614 +3.7118 3.5055 1.5786 +3.7295 3.5581 1.6962 +3.771 3.6106 1.7967 +3.8405 3.6693 1.8628 +3.9049 3.7164 1.8934 +3.9721 3.7622 1.9195 +4.0697 3.8248 1.949 +4.1707 3.8846 1.9717 +4.2575 3.921 1.9684 +4.3491 3.9412 1.9362 +4.4425 3.9512 1.8868 +4.5345 3.9569 1.832 +4.6781 3.9661 1.7182 +4.7918 3.9673 1.5776 +4.8811 3.9513 1.4265 +4.9519 3.9088 1.281 +5.0098 3.8307 1.1573 +2.8091 2.9319 1.2966 +2.8132 2.9929 1.362 +2.8278 3.0633 1.4144 +2.8547 3.1354 1.4549 +2.8954 3.2021 1.4855 +2.9514 3.2565 1.5085 +3.0653 3.3122 1.5202 +3.1912 3.3437 1.5085 +3.3364 3.3656 1.4866 +3.4789 3.3753 1.4565 +3.6056 3.3681 1.4179 +3.7038 3.339 1.37 +3.7631 3.2775 1.3098 +3.7415 3.3548 1.3978 +3.7304 3.418 1.5082 +3.7335 3.4715 1.6292 +3.7547 3.5198 1.7488 +3.7981 3.5672 1.855 +3.8677 3.6182 1.936 +3.9352 3.6609 1.9833 +4.0067 3.7039 2.0224 +4.1063 3.7621 2.0611 +4.2092 3.8198 2.086 +4.2963 3.856 2.0816 +4.387 3.8775 2.0476 +4.478 3.8901 1.9945 +4.5663 3.8991 1.9328 +4.7042 3.9139 1.8071 +4.8143 3.9202 1.6595 +4.9007 3.9104 1.5011 +4.9678 3.8768 1.343 +5.0196 3.8117 1.1961 +2.8144 2.9191 1.2927 +2.8204 2.9768 1.3667 +2.8424 3.03 1.4254 +2.8766 3.0837 1.4725 +2.9227 3.1339 1.5084 +2.9803 3.1769 1.5335 +3.0958 3.2292 1.5458 +3.2201 3.2642 1.5335 +3.3625 3.2934 1.5124 +3.502 3.3129 1.4838 +3.6246 3.3188 1.4446 +3.7169 3.3065 1.3912 +3.7673 3.2671 1.3178 +3.7561 3.3243 1.4228 +3.7554 3.3728 1.5388 +3.7675 3.4153 1.659 +3.7946 3.4543 1.7767 +3.8391 3.4927 1.8851 +3.9036 3.5331 1.9777 +3.9725 3.5711 2.0419 +4.0497 3.6114 2.0938 +4.1508 3.6635 2.1398 +4.2569 3.717 2.1654 +4.346 3.7528 2.1595 +4.4358 3.7772 2.1245 +4.5237 3.7944 2.0693 +4.6069 3.8082 2.0028 +4.7361 3.8305 1.8692 +4.8411 3.8451 1.7182 +4.924 3.8462 1.5563 +4.9868 3.8276 1.3901 +5.0316 3.7834 1.2264 +2.8314 2.9506 1.3628 +2.862 2.9833 1.426 +2.9044 3.0161 1.4795 +2.9564 3.0484 1.521 +3.0159 3.0794 1.548 +3.1331 3.1273 1.5605 +3.2556 3.1666 1.548 +3.3942 3.2058 1.5279 +3.5287 3.2394 1.5008 +3.6455 3.2623 1.4614 +3.731 3.2695 1.404 +3.7723 3.2541 1.3224 +3.7728 3.2861 1.4377 +3.7837 3.3155 1.5557 +3.8055 3.3432 1.6736 +3.839 3.3705 1.7882 +3.885 3.3983 1.8968 +3.9441 3.4277 1.9962 +4.0141 3.4598 2.0734 +4.097 3.4961 2.1352 +4.1997 3.541 2.186 +4.3095 3.5889 2.2114 +4.4009 3.6238 2.2042 +4.4899 3.652 2.1687 +4.5744 3.6752 2.1126 +4.6524 3.6952 2.0434 +4.7729 3.7265 1.9059 +4.8727 3.7511 1.7539 +4.9516 3.7652 1.5911 +5.0093 3.7651 1.4208 +5.0456 3.7471 1.2465 +2.8241 2.8931 1.2898 +2.8498 2.9017 1.3594 +2.8881 2.9147 1.4243 +2.9366 2.9315 1.4806 +2.9929 2.9512 1.5246 +3.0545 2.9731 1.5524 +3.1736 3.0163 1.565 +3.2943 3.0604 1.5524 +3.429 3.1098 1.5329 +3.5583 3.1576 1.5066 +3.6687 3.1986 1.4672 +3.7463 3.2277 1.4083 +3.7775 3.24 1.3238 +3.7894 3.2438 1.4424 +3.81 3.2517 1.5607 +3.8396 3.2632 1.6771 +3.8784 3.278 1.7902 +3.9269 3.2958 1.8983 +3.9851 3.3161 1.9999 +4.0574 3.34 2.0823 +4.1449 3.3691 2.1479 +4.2497 3.4066 2.2004 +4.3627 3.4478 2.2255 +4.4554 3.4816 2.2177 +4.5433 3.5136 2.1822 +4.6249 3.5436 2.1259 +4.699 3.5709 2.0559 +4.8133 3.6131 1.9173 +4.9085 3.6483 1.7655 +4.9828 3.676 1.6028 +5.0342 3.6955 1.4314 +5.0607 3.7062 1.2536 +2.8344 2.8644 1.2927 +2.8684 2.8491 1.3626 +2.9133 2.8426 1.4255 +2.9671 2.844 1.4787 +3.0279 2.8522 1.52 +3.0935 2.866 1.547 +3.2143 2.9041 1.5595 +3.3333 2.9532 1.547 +3.4644 3.0129 1.5271 +3.5886 3.0747 1.5002 +3.6923 3.1336 1.4609 +3.7617 3.185 1.4035 +3.7826 3.2257 1.3221 +3.8041 3.2 1.4365 +3.8314 3.1843 1.554 +3.8657 3.1776 1.6715 +3.9086 3.1788 1.786 +3.9617 3.187 1.8944 +4.0263 3.201 1.9938 +4.1018 3.218 2.0709 +4.1899 3.2399 2.1323 +4.2978 3.2703 2.183 +4.4127 3.3042 2.2082 +4.5052 3.3362 2.201 +4.5913 3.3721 2.1656 +4.6709 3.4092 2.1096 +4.7433 3.4446 2.0406 +4.8557 3.4991 1.903 +4.9478 3.5451 1.7509 +5.0169 3.5858 1.588 +5.0605 3.6243 1.418 +5.0758 3.6638 1.2447 +2.8388 2.8505 1.2959 +2.8773 2.821 1.3665 +2.9288 2.7935 1.4244 +2.9896 2.7743 1.4707 +3.0571 2.7654 1.5062 +3.129 2.7685 1.5313 +3.2512 2.8019 1.5437 +3.3688 2.8558 1.5313 +3.4965 2.9254 1.5103 +3.6155 3.0007 1.4819 +3.7128 3.0761 1.4428 +3.7748 3.147 1.3895 +3.7871 3.2126 1.317 +3.8159 3.1596 1.42 +3.8468 3.1212 1.5346 +3.8834 3.0962 1.6541 +3.9292 3.0837 1.7715 +3.988 3.0826 1.8799 +4.0635 3.0919 1.9723 +4.1415 3.1048 2.0361 +4.2273 3.1211 2.0874 +4.3386 3.1452 2.1331 +4.4543 3.1722 2.1583 +4.5455 3.2021 2.1523 +4.6299 3.2414 2.1174 +4.7082 3.2853 2.0626 +4.7808 3.3288 1.9966 +4.8946 3.3959 1.8627 +4.9845 3.4527 1.7109 +5.0483 3.5059 1.5487 +5.0836 3.5617 1.3832 +5.0884 3.6268 1.2218 +2.882 2.8045 1.3605 +2.9388 2.7597 1.4118 +3.0058 2.7222 1.4515 +3.0796 2.6974 1.4818 +3.1573 2.6907 1.505 +3.2805 2.7203 1.5169 +3.3971 2.7779 1.505 +3.5224 2.8547 1.4831 +3.6376 2.9391 1.4527 +3.7297 3.0267 1.4139 +3.7855 3.114 1.3665 +3.7905 3.2021 1.3087 +3.8241 3.1273 1.3931 +3.8565 3.0707 1.5015 +3.8935 3.0311 1.6214 +3.9409 3.0073 1.7406 +4.0046 2.9984 1.8467 +4.0905 3.0032 1.9273 +4.17 3.0126 1.974 +4.2527 3.0245 2.0123 +4.3666 3.0433 2.0505 +4.4824 3.0649 2.0749 +4.5724 3.0932 2.0702 +4.6557 3.1353 2.0364 +4.7334 3.1846 1.9838 +4.807 3.2349 1.923 +4.9234 3.3135 1.7968 +5.012 3.38 1.6482 +5.0714 3.4436 1.4891 +5.1002 3.5133 1.3319 +5.097 3.5983 1.1887 +2.8431 2.838 1.2802 +2.8892 2.7827 1.3331 +2.9486 2.7296 1.3781 +3.0181 2.6845 1.4153 +3.0946 2.6535 1.4452 +3.1749 2.6423 1.4679 +3.2987 2.6699 1.4786 +3.4147 2.7296 1.4679 +3.539 2.8086 1.446 +3.6526 2.8945 1.4141 +3.7418 2.9876 1.376 +3.793 3.0878 1.3356 +3.7923 3.1954 1.2968 +3.8286 3.1067 1.3556 +3.8615 3.0399 1.4521 +3.898 2.9929 1.5681 +3.9454 2.9635 1.6853 +4.0108 2.9496 1.7856 +4.1012 2.9492 1.8508 +4.1808 2.9542 1.8807 +4.2616 2.962 1.9062 +4.3766 2.9767 1.9349 +4.4924 2.9955 1.957 +4.5822 3.0234 1.9534 +4.6653 3.0671 1.9214 +4.7433 3.1197 1.8727 +4.8178 3.1746 1.819 +4.9356 3.2608 1.705 +5.0239 3.3332 1.563 +5.0816 3.4028 1.4108 +5.1077 3.481 1.2663 +5.101 3.5788 1.1473 +2.8532 2.8095 1.2459 +2.9025 2.7454 1.2819 +2.9627 2.6912 1.3198 +3.0317 2.6489 1.3565 +3.1066 2.6224 1.3888 +3.1851 2.6144 1.4114 +3.3093 2.6421 1.4204 +3.4249 2.7016 1.4114 +3.5489 2.7806 1.3913 +3.6615 2.8665 1.3608 +3.7484 2.9632 1.3271 +3.7963 3.0726 1.2973 +3.7928 3.1914 1.2787 +3.8278 3.1048 1.3163 +3.8621 3.0342 1.3892 +3.9008 2.9797 1.481 +3.9493 2.9413 1.5752 +4.0129 2.9191 1.6554 +4.0971 2.9135 1.7052 +4.1758 2.9162 1.727 +4.2552 2.9217 1.7446 +4.3701 2.934 1.7637 +4.4853 2.9508 1.7774 +4.576 2.9786 1.7723 +4.6599 3.0239 1.7451 +4.7388 3.079 1.7048 +4.8148 3.1363 1.6606 +4.93 3.2257 1.568 +5.0168 3.3068 1.45 +5.0743 3.3876 1.324 +5.1014 3.4761 1.2073 +5.097 3.58 1.1175 +2.8517 2.8135 1.2244 +2.9013 2.7502 1.2512 +2.9633 2.6931 1.2811 +3.0341 2.6472 1.3105 +3.1093 2.6191 1.3371 +3.1855 2.6134 1.3545 +3.3098 2.6433 1.3607 +3.4252 2.7006 1.3545 +3.5495 2.7795 1.3357 +3.6612 2.8662 1.3051 +3.747 2.964 1.2749 +3.7943 3.0739 1.2567 +3.7921 3.191 1.2605 +3.8224 3.1174 1.2762 +3.8575 3.0497 1.3257 +3.8993 2.9914 1.3939 +3.9495 2.9459 1.4655 +4.01 2.9166 1.5254 +4.0824 2.9069 1.5585 +4.1596 2.9087 1.5719 +4.2369 2.9137 1.5819 +4.3512 2.9257 1.5912 +4.465 2.9419 1.5966 +4.5566 2.97 1.5896 +4.6412 3.0161 1.5668 +4.7216 3.072 1.5351 +4.8001 3.1296 1.5012 +4.9109 3.2171 1.4317 +4.9959 3.305 1.3382 +5.0542 3.3958 1.238 +5.085 3.4916 1.1485 +5.0873 3.5948 1.0873 +2.839 2.8526 1.1806 +2.8884 2.7898 1.1828 +2.9511 2.7316 1.21 +3.0232 2.6813 1.2483 +3.0993 2.6492 1.283 +3.1739 2.6452 1.2997 +3.2974 2.6789 1.3019 +3.4136 2.7325 1.2997 +3.5383 2.811 1.2839 +3.6495 2.8991 1.2557 +3.736 2.9941 1.2297 +3.7865 3.0935 1.2205 +3.7897 3.1949 1.243 +3.8148 3.1344 1.2368 +3.8474 3.0742 1.2624 +3.8875 3.0194 1.3066 +3.9354 2.9748 1.356 +3.9913 2.9454 1.3973 +4.0553 2.9359 1.4174 +4.1302 2.9391 1.4224 +4.205 2.9453 1.4253 +4.3176 2.9593 1.425 +4.4296 2.977 1.4226 +4.5217 3.0058 1.4136 +4.6078 3.0514 1.395 +4.6903 3.106 1.3714 +4.772 3.1617 1.3477 +4.8826 3.2441 1.2981 +4.9694 3.331 1.2273 +5.0316 3.4215 1.1523 +5.0681 3.515 1.0901 +5.078 3.6106 1.0575 +2.8856 2.8054 1.1756 +2.947 2.7568 1.1923 +3.017 2.7156 1.2191 +3.0893 2.6902 1.2443 +3.1579 2.6891 1.2562 +3.2808 2.7243 1.2573 +3.3977 2.7763 1.2562 +3.5229 2.8488 1.2439 +3.6365 2.9297 1.2211 +3.7262 3.017 1.2021 +3.7804 3.1083 1.2003 +3.787 3.2006 1.2291 +3.8088 3.1504 1.2169 +3.8391 3.099 1.2261 +3.8771 3.0513 1.2483 +3.9216 3.0121 1.2746 +3.9717 2.9864 1.2965 +4.0264 2.9791 1.3052 +4.0992 2.9844 1.3039 +4.1715 2.9928 1.3009 +4.2823 3.0097 1.2932 +4.3924 3.0297 1.2844 +4.4851 3.0593 1.2741 +4.5727 3.1038 1.2594 +4.6575 3.156 1.2426 +4.7417 3.209 1.2257 +4.8486 3.2822 1.1927 +4.9381 3.3623 1.1458 +5.007 3.4471 1.0977 +5.0524 3.5343 1.061 +5.0712 3.6219 1.0481 +2.9938 3.0285 1.5918 +2.952 3.0249 1.581 +2.9787 3.0582 1.5886 +2.9174 3.0554 1.7579 +2.9329 3.0232 1.7639 +2.8381 3.0149 1.9201 +2.8229 3.0497 1.9112 +2.702 3.0418 2.0466 +2.7163 3.0042 2.0584 +2.5796 2.9923 2.1681 +2.5687 3.0336 2.1522 +2.4188 3.0239 2.2219 +2.426 2.9788 2.2407 +2.2605 2.9644 2.2587 +2.2579 3.0107 2.2395 +2.2371 2.994 2.2227 +2.2386 2.9624 2.2357 +2.2168 2.9605 2.2117 +2.2163 2.977 2.2049 +2.0763 2.9683 2.1762 +2.0739 2.948 2.1834 +1.9406 2.9364 2.1339 +1.9456 2.9654 2.1247 +1.8371 2.9584 2.0395 +1.8305 2.9267 2.0483 +1.8283 2.9266 2.0264 +1.8329 2.9485 2.0203 +1.8286 2.9386 2.0011 +1.8261 2.9264 2.0045 +1.7139 2.9165 1.8924 +1.718 2.9344 1.8879 +1.6131 2.931 1.77 +1.6075 2.9072 1.7758 +1.6101 2.9075 1.7601 +1.6137 2.9228 1.7563 +1.6125 2.9077 1.7444 +1.5712 2.9041 1.7022 +1.5836 2.9226 1.692 +1.5281 2.9211 1.6526 +1.5228 2.8998 1.6575 +1.4917 2.8971 1.6154 +1.4969 2.9183 1.6105 +1.5025 2.898 1.5811 +2.9477 3.0684 1.5809 +2.8861 3.0665 1.743 +2.7929 3.0621 1.8894 +2.6745 3.0555 2.0183 +2.5494 3.0493 2.1141 +2.4095 3.042 2.1768 +2.2596 3.0301 2.1933 +2.2386 3.0072 2.1914 +2.2178 2.984 2.1886 +2.0849 2.9774 2.1585 +1.9625 2.9787 2.1024 +1.8584 2.9731 2.0183 +1.8477 2.9587 2.0056 +1.846 2.9401 1.9847 +1.7308 2.9427 1.8769 +1.6306 2.9422 1.7559 +1.625 2.93 1.7472 +1.625 2.9156 1.7343 +1.5441 2.9312 1.6406 +1.513 2.9283 1.5987 +2.919 3.053 1.5732 +2.8572 3.0501 1.728 +2.7654 3.0447 1.8675 +2.6497 3.0372 1.99 +2.5332 3.0303 2.076 +2.4034 3.0224 2.1319 +2.2646 3.0113 2.147 +2.2424 2.9944 2.16 +2.2205 2.9774 2.1723 +2.095 2.97 2.1408 +1.9815 2.9685 2.0801 +1.8819 2.9623 1.9971 +1.864 2.9512 1.9909 +1.7449 2.9367 1.8659 +1.6498 2.9342 1.7417 +1.6373 2.9248 1.7381 +1.5939 2.9183 1.6847 +1.5617 2.9241 1.6285 +1.5306 2.9212 1.5869 +2.9094 3.0211 1.57 +2.8476 3.0157 1.7221 +2.7566 3.0078 1.8587 +2.6422 2.9978 1.9782 +2.5296 2.9879 2.0602 +2.4042 2.9769 2.1132 +2.27 2.9652 2.1278 +2.2464 2.9631 2.147 +2.2229 2.9611 2.1656 +2.1009 2.9504 2.1336 +1.9914 2.9408 2.071 +1.8939 2.9323 1.9883 +1.8723 2.9304 1.9848 +1.8507 2.9285 1.9813 +1.752 2.9199 1.8614 +1.6594 2.9118 1.7359 +1.6435 2.9104 1.7343 +1.6262 2.902 1.7343 +1.5992 2.9065 1.6818 +1.5707 2.904 1.6236 +1.5394 2.9013 1.5821 +2.9244 2.9914 1.5732 +2.8631 2.9835 1.728 +2.7717 2.9729 1.8675 +2.6564 2.9602 1.99 +2.5405 2.9468 2.076 +2.4113 2.932 2.1319 +2.2727 2.9189 2.147 +2.2479 2.9316 2.16 +2.2234 2.9446 2.1723 +2.0985 2.9301 2.1408 +1.9864 2.9119 2.0801 +1.8873 2.9007 1.9971 +1.8677 2.9085 1.9909 +1.8481 2.9163 1.9847 +1.7479 2.902 1.8659 +1.6538 2.888 1.7417 +1.6399 2.8951 1.7381 +1.5866 2.888 1.692 +1.5654 2.8827 1.6285 +1.5342 2.8801 1.5869 +2.9554 2.9812 1.5809 +2.8943 2.9724 1.743 +2.8017 2.9606 1.8893 +2.684 2.9465 2.0183 +2.5598 2.9309 2.1141 +2.4207 2.9138 2.1768 +2.271 2.8994 2.1933 +2.2464 2.9184 2.1914 +2.2219 2.9376 2.1886 +2.0899 2.921 2.1585 +1.9695 2.8985 2.1024 +1.866 2.8859 2.0183 +1.8529 2.8983 2.0056 +1.8307 2.9147 2.0011 +1.7351 2.8937 1.8769 +1.6363 2.8768 1.7559 +1.6287 2.8878 1.7472 +1.5492 2.8726 1.6406 +1.5181 2.8701 1.5987 +2.9841 2.9966 1.5886 +2.9233 2.9888 1.7579 +2.8292 2.978 1.9112 +2.7088 2.9648 2.0466 +2.576 2.9497 2.1522 +2.4268 2.9332 2.2219 +2.266 2.9183 2.2395 +2.2426 2.9312 2.2227 +2.2191 2.9442 2.2049 +2.0798 2.9285 2.1762 +1.9506 2.9087 2.1247 +1.8425 2.8967 2.0395 +1.8366 2.9058 2.0203 +1.721 2.8997 1.8879 +1.6171 2.8848 1.77 +1.6163 2.893 1.7563 +1.5764 2.8922 1.6992 +1.5317 2.8798 1.6526 +1.5005 2.8772 1.6105 +3 0 1 2 +3 0 2 3 +3 4 0 3 +3 5 4 3 +3 5 3 6 +3 5 6 7 +3 8 5 7 +3 9 8 7 +3 9 7 10 +3 9 10 11 +3 12 9 11 +3 13 12 11 +3 13 11 14 +3 13 14 15 +3 16 15 17 +3 16 17 18 +3 19 16 18 +3 20 19 18 +3 20 18 21 +3 20 21 22 +3 23 20 22 +3 24 23 22 +3 24 22 25 +3 24 25 26 +3 27 24 26 +3 28 27 26 +3 28 26 29 +3 28 29 30 +3 31 28 30 +3 32 31 30 +3 32 30 33 +3 32 33 34 +3 35 32 34 +3 36 35 34 +3 36 34 37 +3 36 37 38 +3 39 36 38 +3 40 39 38 +3 40 38 41 +3 40 41 42 +3 2 1 43 +3 3 2 43 +3 3 43 44 +3 3 44 45 +3 6 3 45 +3 7 6 45 +3 10 7 46 +3 11 10 46 +3 11 46 47 +3 11 47 48 +3 14 11 48 +3 15 14 48 +3 15 48 49 +3 15 49 50 +3 17 15 50 +3 18 17 50 +3 18 50 51 +3 18 51 52 +3 21 18 52 +3 22 21 52 +3 22 52 53 +3 22 53 54 +3 25 22 54 +3 26 25 54 +3 26 54 55 +3 26 55 56 +3 29 26 56 +3 30 29 56 +3 30 56 57 +3 30 57 58 +3 33 30 58 +3 34 33 58 +3 34 58 59 +3 34 59 60 +3 37 34 60 +3 38 37 60 +3 38 60 61 +3 38 61 62 +3 41 38 62 +3 42 41 62 +3 43 1 63 +3 43 63 64 +3 44 43 64 +3 45 44 64 +3 7 45 65 +3 46 7 65 +3 46 65 66 +3 46 66 67 +3 47 46 67 +3 48 47 67 +3 48 67 68 +3 48 68 49 +3 50 49 69 +3 50 69 70 +3 51 50 70 +3 52 51 70 +3 52 70 71 +3 52 71 72 +3 53 52 72 +3 54 53 72 +3 54 72 73 +3 54 73 74 +3 55 54 74 +3 56 55 74 +3 56 74 75 +3 56 75 76 +3 57 56 76 +3 58 57 76 +3 58 76 77 +3 58 77 78 +3 59 58 78 +3 60 59 78 +3 60 78 79 +3 60 79 80 +3 61 60 80 +3 62 61 80 +3 62 80 81 +3 62 81 42 +3 63 1 82 +3 64 63 82 +3 64 82 83 +3 64 83 84 +3 45 64 84 +3 65 45 84 +3 66 65 85 +3 67 66 85 +3 67 85 86 +3 67 86 87 +3 68 67 87 +3 49 68 87 +3 49 87 88 +3 49 88 89 +3 69 49 89 +3 70 69 89 +3 70 89 90 +3 70 90 91 +3 71 70 91 +3 72 71 91 +3 72 91 92 +3 72 92 93 +3 73 72 93 +3 74 73 93 +3 74 93 94 +3 74 94 95 +3 75 74 95 +3 76 75 95 +3 76 95 96 +3 76 96 97 +3 77 76 97 +3 78 77 97 +3 78 97 98 +3 78 98 99 +3 79 78 99 +3 80 79 99 +3 80 99 100 +3 80 100 101 +3 81 80 101 +3 42 81 101 +3 82 1 102 +3 82 102 103 +3 83 82 103 +3 84 83 103 +3 84 103 104 +3 84 104 105 +3 65 84 105 +3 85 65 105 +3 85 105 106 +3 85 106 107 +3 86 85 107 +3 87 86 107 +3 87 107 108 +3 87 108 88 +3 89 88 109 +3 89 109 110 +3 90 89 110 +3 91 90 110 +3 91 110 111 +3 91 111 112 +3 92 91 112 +3 93 92 112 +3 93 112 113 +3 93 113 114 +3 94 93 114 +3 95 94 114 +3 95 114 115 +3 95 115 116 +3 96 95 116 +3 97 96 116 +3 97 116 117 +3 97 117 118 +3 98 97 118 +3 99 98 118 +3 99 118 119 +3 99 119 120 +3 100 99 120 +3 101 100 120 +3 101 120 121 +3 101 121 42 +3 102 1 122 +3 103 102 122 +3 103 122 123 +3 103 123 124 +3 104 103 124 +3 105 104 124 +3 106 105 125 +3 107 106 125 +3 107 125 126 +3 107 126 127 +3 108 107 127 +3 88 108 127 +3 88 127 128 +3 88 128 129 +3 109 88 129 +3 110 109 129 +3 110 129 130 +3 110 130 131 +3 111 110 131 +3 112 111 131 +3 112 131 132 +3 112 132 133 +3 113 112 133 +3 114 113 133 +3 114 133 134 +3 114 134 135 +3 115 114 135 +3 116 115 135 +3 116 135 136 +3 116 136 137 +3 117 116 137 +3 118 117 137 +3 118 137 138 +3 118 138 139 +3 119 118 139 +3 120 119 139 +3 120 139 140 +3 120 140 141 +3 121 120 141 +3 42 121 141 +3 122 1 142 +3 122 142 143 +3 123 122 143 +3 124 123 143 +3 105 124 8 +3 125 105 8 +3 125 8 144 +3 125 144 145 +3 126 125 145 +3 127 126 145 +3 127 145 146 +3 127 146 128 +3 129 128 147 +3 129 147 148 +3 130 129 148 +3 131 130 148 +3 131 148 149 +3 131 149 150 +3 132 131 150 +3 133 132 150 +3 133 150 151 +3 133 151 152 +3 134 133 152 +3 135 134 152 +3 135 152 153 +3 135 153 154 +3 136 135 154 +3 137 136 154 +3 137 154 155 +3 137 155 156 +3 138 137 156 +3 139 138 156 +3 139 156 157 +3 139 157 158 +3 140 139 158 +3 141 140 158 +3 141 158 159 +3 141 159 42 +3 142 1 0 +3 143 142 0 +3 143 0 4 +3 143 4 5 +3 124 143 5 +3 8 124 5 +3 144 8 9 +3 145 144 9 +3 145 9 12 +3 145 12 13 +3 146 145 13 +3 128 146 13 +3 128 13 15 +3 128 15 16 +3 147 128 16 +3 148 147 16 +3 148 16 19 +3 148 19 20 +3 149 148 20 +3 150 149 20 +3 150 20 23 +3 150 23 24 +3 151 150 24 +3 152 151 24 +3 152 24 27 +3 152 27 28 +3 153 152 28 +3 154 153 28 +3 154 28 31 +3 154 31 32 +3 155 154 32 +3 156 155 32 +3 156 32 35 +3 156 35 36 +3 157 156 36 +3 158 157 36 +3 158 36 39 +3 158 39 40 +3 159 158 40 +3 42 159 40 +3 160 161 162 +3 163 160 162 +3 162 161 164 +3 162 164 165 +3 163 162 165 +3 166 163 165 +3 166 165 167 +3 166 167 168 +3 169 166 168 +3 164 161 170 +3 165 164 170 +3 170 161 171 +3 165 170 171 +3 165 171 172 +3 165 172 173 +3 167 165 173 +3 168 167 173 +3 168 173 174 +3 171 161 175 +3 171 175 176 +3 172 171 176 +3 173 172 176 +3 175 161 177 +3 176 175 177 +3 176 177 178 +3 176 178 179 +3 173 176 179 +3 174 173 179 +3 177 161 180 +3 177 180 181 +3 178 177 181 +3 179 178 181 +3 179 181 182 +3 179 182 174 +3 180 161 183 +3 181 180 183 +3 181 183 184 +3 181 184 182 +3 183 161 185 +3 183 185 186 +3 184 183 186 +3 182 184 186 +3 182 186 187 +3 182 187 168 +3 174 182 168 +3 185 161 188 +3 186 185 188 +3 186 188 189 +3 186 189 190 +3 187 186 190 +3 168 187 190 +3 168 190 169 +3 188 161 191 +3 188 191 192 +3 189 188 192 +3 190 189 192 +3 191 161 193 +3 192 191 193 +3 192 193 194 +3 192 194 195 +3 190 192 195 +3 169 190 195 +3 193 161 160 +3 193 160 163 +3 194 193 163 +3 195 194 163 +3 195 163 166 +3 195 166 169 +3 196 197 198 +3 196 198 199 +3 200 201 202 +3 203 200 202 +3 197 203 202 +3 197 202 204 +3 197 204 205 +3 198 197 205 +3 199 198 205 +3 205 204 206 +3 205 206 199 +3 202 201 207 +3 202 207 208 +3 202 208 209 +3 204 202 209 +3 206 204 209 +3 206 209 210 +3 206 210 199 +3 209 208 211 +3 209 211 212 +3 210 209 212 +3 199 210 212 +3 208 207 213 +3 208 213 214 +3 211 208 214 +3 212 211 214 +3 212 214 215 +3 212 215 199 +3 213 207 216 +3 214 213 216 +3 214 216 217 +3 214 217 218 +3 215 214 218 +3 199 215 218 +3 218 217 219 +3 218 219 199 +3 207 201 220 +3 216 207 220 +3 217 216 220 +3 217 220 221 +3 217 221 222 +3 219 217 222 +3 199 219 222 +3 220 201 200 +3 220 200 223 +3 220 223 224 +3 221 220 224 +3 222 221 224 +3 222 224 225 +3 222 225 199 +3 224 223 226 +3 224 226 227 +3 225 224 227 +3 199 225 227 +3 223 200 228 +3 223 228 229 +3 226 223 229 +3 227 226 229 +3 227 229 230 +3 227 230 199 +3 228 200 203 +3 229 228 203 +3 229 203 197 +3 229 197 196 +3 230 229 196 +3 199 230 196 +3 231 232 233 +3 231 233 234 +3 235 231 234 +3 236 235 234 +3 236 234 237 +3 236 237 238 +3 233 232 239 +3 234 233 239 +3 234 239 240 +3 234 240 241 +3 237 234 241 +3 238 237 241 +3 239 232 242 +3 239 242 243 +3 240 239 243 +3 241 240 243 +3 241 243 244 +3 241 244 238 +3 242 232 245 +3 243 242 245 +3 243 245 246 +3 243 246 247 +3 244 243 247 +3 238 244 247 +3 245 232 248 +3 245 248 249 +3 246 245 249 +3 247 246 249 +3 247 249 250 +3 247 250 238 +3 248 232 251 +3 249 248 251 +3 249 251 252 +3 249 252 253 +3 250 249 253 +3 238 250 253 +3 251 232 254 +3 251 254 255 +3 252 251 255 +3 253 252 255 +3 253 255 256 +3 253 256 238 +3 254 232 257 +3 255 254 257 +3 255 257 258 +3 255 258 259 +3 256 255 259 +3 238 256 259 +3 257 232 260 +3 257 260 261 +3 258 257 261 +3 259 258 261 +3 259 261 262 +3 259 262 238 +3 260 232 263 +3 261 260 263 +3 261 263 264 +3 261 264 265 +3 262 261 265 +3 238 262 265 +3 263 232 266 +3 263 266 267 +3 264 263 267 +3 265 264 267 +3 265 267 268 +3 265 268 238 +3 266 232 231 +3 267 266 231 +3 267 231 235 +3 267 235 236 +3 268 267 236 +3 238 268 236 +3 269 270 271 +3 269 271 272 +3 273 269 272 +3 274 273 272 +3 274 272 275 +3 274 275 276 +3 271 270 277 +3 272 271 277 +3 272 277 278 +3 272 278 279 +3 275 272 279 +3 276 275 279 +3 277 270 280 +3 277 280 281 +3 278 277 281 +3 279 278 281 +3 279 281 282 +3 279 282 276 +3 280 270 283 +3 281 280 283 +3 281 283 284 +3 281 284 285 +3 282 281 285 +3 276 282 285 +3 283 270 286 +3 283 286 287 +3 284 283 287 +3 285 284 287 +3 285 287 288 +3 285 288 276 +3 286 270 289 +3 287 286 289 +3 287 289 290 +3 287 290 291 +3 288 287 291 +3 276 288 291 +3 289 270 292 +3 289 292 293 +3 290 289 293 +3 291 290 293 +3 291 293 294 +3 291 294 276 +3 292 270 295 +3 293 292 295 +3 293 295 296 +3 293 296 297 +3 294 293 297 +3 276 294 297 +3 295 270 298 +3 295 298 299 +3 296 295 299 +3 297 296 299 +3 297 299 300 +3 297 300 276 +3 298 270 301 +3 299 298 301 +3 299 301 302 +3 299 302 303 +3 300 299 303 +3 276 300 303 +3 301 270 304 +3 301 304 305 +3 302 301 305 +3 303 302 305 +3 303 305 306 +3 303 306 276 +3 304 270 269 +3 305 304 269 +3 305 269 273 +3 305 273 274 +3 306 305 274 +3 276 306 274 +3 307 308 309 +3 307 309 310 +3 311 307 310 +3 312 311 310 +3 312 310 313 +3 312 313 314 +3 315 312 314 +3 316 315 314 +3 316 314 317 +3 316 317 318 +3 319 316 318 +3 320 319 318 +3 320 318 321 +3 320 321 322 +3 323 320 322 +3 324 323 322 +3 324 322 325 +3 324 325 326 +3 327 324 326 +3 328 327 326 +3 328 326 329 +3 328 329 330 +3 331 328 330 +3 332 331 330 +3 332 330 333 +3 332 333 334 +3 335 332 334 +3 336 335 334 +3 336 334 337 +3 336 337 338 +3 339 336 338 +3 340 339 338 +3 340 338 341 +3 340 341 342 +3 309 308 343 +3 310 309 343 +3 310 343 344 +3 310 344 345 +3 313 310 345 +3 314 313 345 +3 314 345 346 +3 314 346 347 +3 317 314 347 +3 318 317 347 +3 318 347 348 +3 318 348 349 +3 321 318 349 +3 322 321 349 +3 322 349 350 +3 322 350 351 +3 325 322 351 +3 326 325 351 +3 326 351 352 +3 326 352 353 +3 329 326 353 +3 330 329 353 +3 330 353 354 +3 330 354 355 +3 333 330 355 +3 334 333 355 +3 334 355 356 +3 334 356 357 +3 337 334 357 +3 338 337 357 +3 338 357 358 +3 338 358 341 +3 343 308 359 +3 343 359 360 +3 344 343 360 +3 345 344 360 +3 345 360 361 +3 345 361 362 +3 346 345 362 +3 347 346 362 +3 347 362 363 +3 347 363 364 +3 348 347 364 +3 349 348 364 +3 349 364 365 +3 349 365 366 +3 350 349 366 +3 351 350 366 +3 351 366 367 +3 351 367 368 +3 352 351 368 +3 353 352 368 +3 353 368 369 +3 353 369 370 +3 354 353 370 +3 355 354 370 +3 355 370 371 +3 355 371 372 +3 356 355 372 +3 357 356 372 +3 359 308 373 +3 360 359 373 +3 360 373 374 +3 360 374 375 +3 361 360 375 +3 362 361 375 +3 362 375 376 +3 362 376 377 +3 363 362 377 +3 364 363 377 +3 364 377 378 +3 364 378 379 +3 365 364 379 +3 366 365 379 +3 366 379 380 +3 366 380 381 +3 367 366 381 +3 368 367 381 +3 368 381 382 +3 368 382 383 +3 369 368 383 +3 370 369 383 +3 370 383 384 +3 370 384 385 +3 371 370 385 +3 372 371 385 +3 372 385 386 +3 372 386 387 +3 357 372 387 +3 358 357 387 +3 358 387 388 +3 358 388 389 +3 341 358 389 +3 342 341 389 +3 373 308 390 +3 373 390 391 +3 374 373 391 +3 375 374 391 +3 375 391 392 +3 375 392 393 +3 376 375 393 +3 377 376 393 +3 377 393 394 +3 377 394 395 +3 378 377 395 +3 379 378 395 +3 379 395 396 +3 379 396 397 +3 380 379 397 +3 381 380 397 +3 381 397 398 +3 381 398 399 +3 382 381 399 +3 383 382 399 +3 383 399 400 +3 383 400 401 +3 384 383 401 +3 385 384 401 +3 385 401 402 +3 385 402 403 +3 386 385 403 +3 387 386 403 +3 387 403 404 +3 387 404 405 +3 388 387 405 +3 389 388 405 +3 389 405 406 +3 389 406 342 +3 390 308 407 +3 391 390 407 +3 391 407 408 +3 391 408 409 +3 392 391 409 +3 393 392 409 +3 393 409 410 +3 393 410 411 +3 394 393 411 +3 395 394 411 +3 395 411 412 +3 395 412 413 +3 396 395 413 +3 397 396 413 +3 397 413 414 +3 397 414 415 +3 398 397 415 +3 399 398 415 +3 399 415 416 +3 399 416 417 +3 400 399 417 +3 401 400 417 +3 401 417 418 +3 401 418 419 +3 402 401 419 +3 403 402 419 +3 403 419 420 +3 403 420 421 +3 404 403 421 +3 405 404 421 +3 405 421 422 +3 405 422 406 +3 407 308 423 +3 407 423 424 +3 408 407 424 +3 409 408 424 +3 409 424 425 +3 409 425 426 +3 410 409 426 +3 411 410 426 +3 411 426 427 +3 411 427 428 +3 412 411 428 +3 413 412 428 +3 413 428 429 +3 413 429 430 +3 414 413 430 +3 415 414 430 +3 415 430 431 +3 415 431 432 +3 416 415 432 +3 417 416 432 +3 417 432 433 +3 417 433 434 +3 418 417 434 +3 419 418 434 +3 419 434 435 +3 419 435 436 +3 420 419 436 +3 421 420 436 +3 423 308 437 +3 424 423 437 +3 424 437 438 +3 424 438 439 +3 425 424 439 +3 426 425 439 +3 426 439 440 +3 426 440 441 +3 427 426 441 +3 428 427 441 +3 428 441 442 +3 428 442 443 +3 429 428 443 +3 430 429 443 +3 430 443 444 +3 430 444 445 +3 431 430 445 +3 432 431 445 +3 432 445 446 +3 432 446 447 +3 433 432 447 +3 434 433 447 +3 434 447 448 +3 434 448 449 +3 435 434 449 +3 436 435 449 +3 436 449 450 +3 436 450 451 +3 421 436 451 +3 422 421 451 +3 422 451 452 +3 422 452 453 +3 406 422 453 +3 342 406 453 +3 437 308 454 +3 437 454 455 +3 438 437 455 +3 439 438 455 +3 439 455 456 +3 439 456 457 +3 440 439 457 +3 441 440 457 +3 441 457 458 +3 441 458 459 +3 442 441 459 +3 443 442 459 +3 443 459 460 +3 443 460 461 +3 444 443 461 +3 445 444 461 +3 445 461 462 +3 445 462 463 +3 446 445 463 +3 447 446 463 +3 447 463 464 +3 447 464 465 +3 448 447 465 +3 449 448 465 +3 449 465 466 +3 449 466 467 +3 450 449 467 +3 451 450 467 +3 451 467 468 +3 451 468 469 +3 452 451 469 +3 453 452 469 +3 453 469 470 +3 453 470 342 +3 455 454 471 +3 455 471 472 +3 456 455 472 +3 457 456 472 +3 457 472 473 +3 457 473 474 +3 458 457 474 +3 459 458 474 +3 459 474 475 +3 459 475 476 +3 460 459 476 +3 461 460 476 +3 461 476 477 +3 461 477 478 +3 462 461 478 +3 463 462 478 +3 463 478 479 +3 463 479 480 +3 464 463 480 +3 465 464 480 +3 465 480 481 +3 465 481 482 +3 466 465 482 +3 467 466 482 +3 467 482 483 +3 467 483 484 +3 468 467 484 +3 469 468 484 +3 469 484 485 +3 469 485 486 +3 470 469 486 +3 342 470 486 +3 454 308 487 +3 454 487 488 +3 471 454 488 +3 472 471 488 +3 472 488 489 +3 472 489 490 +3 473 472 490 +3 474 473 490 +3 474 490 491 +3 474 491 492 +3 475 474 492 +3 476 475 492 +3 476 492 493 +3 476 493 494 +3 477 476 494 +3 478 477 494 +3 478 494 495 +3 478 495 496 +3 479 478 496 +3 480 479 496 +3 480 496 497 +3 480 497 498 +3 481 480 498 +3 482 481 498 +3 482 498 499 +3 482 499 500 +3 483 482 500 +3 484 483 500 +3 484 500 501 +3 484 501 502 +3 485 484 502 +3 486 485 502 +3 486 502 503 +3 486 503 342 +3 488 487 504 +3 488 504 505 +3 489 488 505 +3 490 489 505 +3 490 505 506 +3 490 506 507 +3 491 490 507 +3 492 491 507 +3 492 507 508 +3 492 508 509 +3 493 492 509 +3 494 493 509 +3 494 509 510 +3 494 510 511 +3 495 494 511 +3 496 495 511 +3 496 511 512 +3 496 512 513 +3 497 496 513 +3 498 497 513 +3 498 513 514 +3 498 514 515 +3 499 498 515 +3 500 499 515 +3 500 515 516 +3 500 516 517 +3 501 500 517 +3 502 501 517 +3 502 517 518 +3 502 518 519 +3 503 502 519 +3 342 503 519 +3 487 308 520 +3 487 520 521 +3 504 487 521 +3 505 504 521 +3 505 521 522 +3 505 522 523 +3 506 505 523 +3 507 506 523 +3 507 523 524 +3 507 524 525 +3 508 507 525 +3 509 508 525 +3 509 525 526 +3 509 526 527 +3 510 509 527 +3 511 510 527 +3 511 527 528 +3 511 528 529 +3 512 511 529 +3 513 512 529 +3 513 529 530 +3 513 530 531 +3 514 513 531 +3 515 514 531 +3 515 531 532 +3 515 532 533 +3 516 515 533 +3 517 516 533 +3 517 533 534 +3 517 534 535 +3 518 517 535 +3 519 518 535 +3 519 535 536 +3 519 536 342 +3 520 308 537 +3 521 520 537 +3 521 537 538 +3 521 538 539 +3 522 521 539 +3 523 522 539 +3 523 539 540 +3 523 540 541 +3 524 523 541 +3 525 524 541 +3 525 541 542 +3 525 542 543 +3 526 525 543 +3 527 526 543 +3 527 543 544 +3 527 544 545 +3 528 527 545 +3 529 528 545 +3 529 545 546 +3 529 546 547 +3 530 529 547 +3 531 530 547 +3 531 547 548 +3 531 548 549 +3 532 531 549 +3 533 532 549 +3 533 549 550 +3 533 550 551 +3 534 533 551 +3 535 534 551 +3 535 551 552 +3 535 552 553 +3 536 535 553 +3 342 536 553 +3 539 538 554 +3 539 554 555 +3 540 539 555 +3 541 540 555 +3 541 555 556 +3 541 556 557 +3 542 541 557 +3 543 542 557 +3 543 557 558 +3 543 558 559 +3 544 543 559 +3 545 544 559 +3 545 559 560 +3 545 560 561 +3 546 545 561 +3 547 546 561 +3 547 561 562 +3 547 562 563 +3 548 547 563 +3 549 548 563 +3 549 563 564 +3 549 564 565 +3 550 549 565 +3 551 550 565 +3 551 565 566 +3 551 566 567 +3 552 551 567 +3 553 552 567 +3 553 567 568 +3 553 568 342 +3 537 308 569 +3 538 537 569 +3 538 569 570 +3 538 570 571 +3 554 538 571 +3 555 554 571 +3 555 571 572 +3 555 572 573 +3 556 555 573 +3 557 556 573 +3 557 573 574 +3 557 574 575 +3 558 557 575 +3 559 558 575 +3 559 575 576 +3 559 576 577 +3 560 559 577 +3 561 560 577 +3 561 577 578 +3 561 578 579 +3 562 561 579 +3 563 562 579 +3 563 579 580 +3 563 580 581 +3 564 563 581 +3 565 564 581 +3 565 581 582 +3 565 582 583 +3 566 565 583 +3 567 566 583 +3 567 583 584 +3 567 584 585 +3 568 567 585 +3 342 568 585 +3 569 308 586 +3 569 586 587 +3 570 569 587 +3 571 570 587 +3 571 587 588 +3 571 588 589 +3 572 571 589 +3 573 572 589 +3 573 589 590 +3 573 590 591 +3 574 573 591 +3 575 574 591 +3 575 591 592 +3 575 592 593 +3 576 575 593 +3 577 576 593 +3 577 593 594 +3 577 594 595 +3 578 577 595 +3 579 578 595 +3 579 595 596 +3 579 596 597 +3 580 579 597 +3 581 580 597 +3 581 597 598 +3 581 598 599 +3 582 581 599 +3 583 582 599 +3 583 599 600 +3 583 600 601 +3 584 583 601 +3 585 584 601 +3 585 601 602 +3 585 602 342 +3 586 308 603 +3 587 586 603 +3 587 603 604 +3 587 604 605 +3 588 587 605 +3 589 588 605 +3 589 605 606 +3 589 606 607 +3 590 589 607 +3 591 590 607 +3 591 607 608 +3 591 608 609 +3 592 591 609 +3 593 592 609 +3 593 609 610 +3 593 610 611 +3 594 593 611 +3 595 594 611 +3 595 611 612 +3 595 612 613 +3 596 595 613 +3 597 596 613 +3 597 613 614 +3 597 614 615 +3 598 597 615 +3 599 598 615 +3 599 615 616 +3 599 616 617 +3 600 599 617 +3 601 600 617 +3 601 617 618 +3 601 618 619 +3 602 601 619 +3 342 602 619 +3 603 308 620 +3 603 620 621 +3 604 603 621 +3 605 604 621 +3 605 621 622 +3 605 622 623 +3 606 605 623 +3 607 606 623 +3 607 623 624 +3 607 624 625 +3 608 607 625 +3 609 608 625 +3 609 625 626 +3 609 626 627 +3 610 609 627 +3 611 610 627 +3 611 627 628 +3 611 628 629 +3 612 611 629 +3 613 612 629 +3 613 629 630 +3 613 630 631 +3 614 613 631 +3 615 614 631 +3 615 631 632 +3 615 632 633 +3 616 615 633 +3 617 616 633 +3 617 633 634 +3 617 634 635 +3 618 617 635 +3 619 618 635 +3 619 635 636 +3 619 636 342 +3 622 621 637 +3 623 622 637 +3 623 637 638 +3 623 638 639 +3 624 623 639 +3 625 624 639 +3 625 639 640 +3 625 640 641 +3 626 625 641 +3 627 626 641 +3 627 641 642 +3 627 642 643 +3 628 627 643 +3 629 628 643 +3 629 643 644 +3 629 644 645 +3 630 629 645 +3 631 630 645 +3 631 645 646 +3 631 646 647 +3 632 631 647 +3 633 632 647 +3 633 647 648 +3 633 648 649 +3 634 633 649 +3 635 634 649 +3 635 649 650 +3 635 650 651 +3 636 635 651 +3 342 636 651 +3 620 308 652 +3 620 652 653 +3 621 620 653 +3 637 621 653 +3 637 653 654 +3 637 654 655 +3 638 637 655 +3 639 638 655 +3 639 655 656 +3 639 656 657 +3 640 639 657 +3 641 640 657 +3 641 657 658 +3 641 658 659 +3 642 641 659 +3 643 642 659 +3 643 659 660 +3 643 660 661 +3 644 643 661 +3 645 644 661 +3 645 661 662 +3 645 662 663 +3 646 645 663 +3 647 646 663 +3 647 663 664 +3 647 664 665 +3 648 647 665 +3 649 648 665 +3 649 665 666 +3 649 666 667 +3 650 649 667 +3 651 650 667 +3 651 667 668 +3 651 668 342 +3 652 308 669 +3 653 652 669 +3 653 669 670 +3 653 670 671 +3 654 653 671 +3 655 654 671 +3 655 671 672 +3 655 672 673 +3 656 655 673 +3 657 656 673 +3 657 673 674 +3 657 674 675 +3 658 657 675 +3 659 658 675 +3 659 675 676 +3 659 676 677 +3 660 659 677 +3 661 660 677 +3 661 677 678 +3 661 678 679 +3 662 661 679 +3 663 662 679 +3 663 679 680 +3 663 680 681 +3 664 663 681 +3 665 664 681 +3 665 681 682 +3 665 682 683 +3 666 665 683 +3 667 666 683 +3 667 683 684 +3 667 684 685 +3 668 667 685 +3 342 668 685 +3 669 308 686 +3 669 686 687 +3 670 669 687 +3 671 670 687 +3 671 687 688 +3 671 688 689 +3 672 671 689 +3 673 672 689 +3 673 689 690 +3 673 690 691 +3 674 673 691 +3 675 674 691 +3 675 691 692 +3 675 692 693 +3 676 675 693 +3 677 676 693 +3 677 693 694 +3 677 694 695 +3 678 677 695 +3 679 678 695 +3 679 695 696 +3 679 696 697 +3 680 679 697 +3 681 680 697 +3 681 697 698 +3 681 698 699 +3 682 681 699 +3 683 682 699 +3 683 699 700 +3 683 700 701 +3 684 683 701 +3 685 684 701 +3 685 701 702 +3 685 702 342 +3 686 308 703 +3 687 686 703 +3 687 703 704 +3 687 704 705 +3 688 687 705 +3 689 688 705 +3 689 705 706 +3 689 706 707 +3 690 689 707 +3 691 690 707 +3 691 707 708 +3 691 708 709 +3 692 691 709 +3 693 692 709 +3 693 709 710 +3 693 710 711 +3 694 693 711 +3 695 694 711 +3 695 711 712 +3 695 712 713 +3 696 695 713 +3 697 696 713 +3 697 713 714 +3 697 714 715 +3 698 697 715 +3 699 698 715 +3 699 715 716 +3 699 716 717 +3 700 699 717 +3 701 700 717 +3 701 717 718 +3 701 718 719 +3 702 701 719 +3 342 702 719 +3 703 308 307 +3 703 307 720 +3 704 703 720 +3 705 704 720 +3 705 720 721 +3 705 721 722 +3 706 705 722 +3 707 706 722 +3 707 722 723 +3 707 723 724 +3 708 707 724 +3 709 708 724 +3 709 724 725 +3 709 725 726 +3 710 709 726 +3 711 710 726 +3 711 726 727 +3 711 727 728 +3 712 711 728 +3 713 712 728 +3 713 728 729 +3 713 729 730 +3 714 713 730 +3 715 714 730 +3 715 730 731 +3 715 731 732 +3 716 715 732 +3 717 716 732 +3 717 732 733 +3 717 733 734 +3 718 717 734 +3 719 718 734 +3 719 734 735 +3 719 735 342 +3 720 307 311 +3 720 311 312 +3 721 720 312 +3 722 721 312 +3 722 312 315 +3 722 315 316 +3 723 722 316 +3 724 723 316 +3 724 316 319 +3 724 319 320 +3 725 724 320 +3 726 725 320 +3 726 320 323 +3 726 323 324 +3 727 726 324 +3 728 727 324 +3 728 324 327 +3 728 327 328 +3 729 728 328 +3 730 729 328 +3 730 328 331 +3 730 331 332 +3 731 730 332 +3 732 731 332 +3 732 332 335 +3 732 335 336 +3 733 732 336 +3 734 733 336 +3 734 336 339 +3 734 339 340 +3 735 734 340 +3 342 735 340 +3 736 737 738 +3 736 738 739 +3 740 736 739 +3 741 740 739 +3 741 739 742 +3 741 742 743 +3 744 741 743 +3 745 744 743 +3 745 743 746 +3 745 746 747 +3 748 745 747 +3 749 748 747 +3 749 747 750 +3 749 750 751 +3 752 749 751 +3 753 752 751 +3 753 751 754 +3 753 754 755 +3 756 753 755 +3 757 756 755 +3 757 755 758 +3 757 758 759 +3 760 757 759 +3 761 760 759 +3 761 759 762 +3 761 762 763 +3 764 761 763 +3 765 764 763 +3 765 763 766 +3 765 766 767 +3 768 765 767 +3 769 768 767 +3 769 767 770 +3 769 770 771 +3 772 769 771 +3 773 772 771 +3 773 771 774 +3 773 774 775 +3 776 773 775 +3 777 776 775 +3 777 775 778 +3 777 778 779 +3 780 777 779 +3 781 780 779 +3 781 779 782 +3 781 782 783 +3 784 781 783 +3 785 784 783 +3 785 783 786 +3 785 786 787 +3 788 785 787 +3 789 788 787 +3 789 787 790 +3 789 790 791 +3 792 789 791 +3 793 792 791 +3 793 791 794 +3 793 794 795 +3 796 793 795 +3 797 796 795 +3 797 795 798 +3 797 798 799 +3 800 797 799 +3 801 800 799 +3 801 799 802 +3 801 802 803 +3 804 801 803 +3 805 804 803 +3 805 803 806 +3 805 806 807 +3 808 805 807 +3 809 808 807 +3 809 807 810 +3 809 810 811 +3 812 809 811 +3 813 812 811 +3 813 811 814 +3 813 814 815 +3 816 813 815 +3 817 816 815 +3 817 815 818 +3 817 818 819 +3 820 817 819 +3 821 820 819 +3 821 819 822 +3 821 822 823 +3 824 821 823 +3 825 824 823 +3 825 823 826 +3 825 826 827 +3 738 737 828 +3 739 738 828 +3 739 828 829 +3 739 829 830 +3 742 739 830 +3 743 742 830 +3 743 830 831 +3 743 831 832 +3 746 743 832 +3 747 746 832 +3 747 832 833 +3 747 833 834 +3 750 747 834 +3 751 750 834 +3 751 834 835 +3 751 835 836 +3 754 751 836 +3 755 754 836 +3 755 836 837 +3 755 837 838 +3 758 755 838 +3 759 758 838 +3 759 838 839 +3 759 839 840 +3 762 759 840 +3 763 762 840 +3 763 840 841 +3 763 841 842 +3 766 763 842 +3 767 766 842 +3 767 842 843 +3 767 843 844 +3 770 767 844 +3 771 770 844 +3 771 844 845 +3 771 845 846 +3 774 771 846 +3 775 774 846 +3 775 846 847 +3 775 847 848 +3 778 775 848 +3 779 778 848 +3 779 848 849 +3 779 849 850 +3 782 779 850 +3 783 782 850 +3 783 850 851 +3 783 851 852 +3 786 783 852 +3 787 786 852 +3 787 852 853 +3 787 853 854 +3 790 787 854 +3 791 790 854 +3 791 854 855 +3 791 855 856 +3 794 791 856 +3 795 794 856 +3 795 856 857 +3 795 857 858 +3 798 795 858 +3 799 798 858 +3 799 858 859 +3 799 859 860 +3 802 799 860 +3 803 802 860 +3 803 860 861 +3 803 861 862 +3 806 803 862 +3 807 806 862 +3 807 862 863 +3 807 863 864 +3 810 807 864 +3 811 810 864 +3 811 864 865 +3 811 865 866 +3 814 811 866 +3 815 814 866 +3 815 866 867 +3 815 867 868 +3 818 815 868 +3 819 818 868 +3 819 868 869 +3 819 869 870 +3 822 819 870 +3 823 822 870 +3 823 870 871 +3 823 871 872 +3 826 823 872 +3 827 826 872 +3 828 737 873 +3 828 873 874 +3 829 828 874 +3 830 829 874 +3 830 874 875 +3 830 875 876 +3 831 830 876 +3 832 831 876 +3 832 876 877 +3 832 877 878 +3 833 832 878 +3 834 833 878 +3 834 878 879 +3 834 879 880 +3 835 834 880 +3 836 835 880 +3 836 880 881 +3 836 881 882 +3 837 836 882 +3 838 837 882 +3 838 882 883 +3 838 883 884 +3 839 838 884 +3 840 839 884 +3 840 884 885 +3 840 885 886 +3 841 840 886 +3 842 841 886 +3 842 886 887 +3 842 887 888 +3 843 842 888 +3 844 843 888 +3 844 888 889 +3 844 889 890 +3 845 844 890 +3 846 845 890 +3 846 890 891 +3 846 891 892 +3 847 846 892 +3 848 847 892 +3 848 892 893 +3 848 893 894 +3 849 848 894 +3 850 849 894 +3 850 894 895 +3 850 895 896 +3 851 850 896 +3 852 851 896 +3 852 896 897 +3 852 897 898 +3 853 852 898 +3 854 853 898 +3 854 898 899 +3 854 899 900 +3 855 854 900 +3 856 855 900 +3 856 900 901 +3 856 901 902 +3 857 856 902 +3 858 857 902 +3 858 902 903 +3 858 903 904 +3 859 858 904 +3 860 859 904 +3 860 904 905 +3 860 905 906 +3 861 860 906 +3 862 861 906 +3 862 906 907 +3 862 907 908 +3 863 862 908 +3 864 863 908 +3 864 908 909 +3 864 909 910 +3 865 864 910 +3 866 865 910 +3 866 910 911 +3 866 911 912 +3 867 866 912 +3 868 867 912 +3 868 912 913 +3 868 913 914 +3 869 868 914 +3 870 869 914 +3 870 914 915 +3 870 915 916 +3 871 870 916 +3 872 871 916 +3 872 916 917 +3 872 917 827 +3 873 737 918 +3 874 873 918 +3 874 918 919 +3 874 919 920 +3 875 874 920 +3 876 875 920 +3 876 920 921 +3 876 921 922 +3 877 876 922 +3 878 877 922 +3 878 922 923 +3 878 923 924 +3 879 878 924 +3 880 879 924 +3 880 924 925 +3 880 925 926 +3 881 880 926 +3 882 881 926 +3 882 926 927 +3 882 927 928 +3 883 882 928 +3 884 883 928 +3 884 928 929 +3 884 929 930 +3 885 884 930 +3 886 885 930 +3 886 930 931 +3 886 931 932 +3 887 886 932 +3 888 887 932 +3 888 932 933 +3 888 933 934 +3 889 888 934 +3 890 889 934 +3 890 934 935 +3 890 935 936 +3 891 890 936 +3 892 891 936 +3 892 936 937 +3 892 937 938 +3 893 892 938 +3 894 893 938 +3 894 938 939 +3 894 939 940 +3 895 894 940 +3 896 895 940 +3 896 940 941 +3 896 941 942 +3 897 896 942 +3 898 897 942 +3 898 942 943 +3 898 943 944 +3 899 898 944 +3 900 899 944 +3 900 944 945 +3 900 945 946 +3 901 900 946 +3 902 901 946 +3 902 946 947 +3 902 947 948 +3 903 902 948 +3 904 903 948 +3 904 948 949 +3 904 949 950 +3 905 904 950 +3 906 905 950 +3 906 950 951 +3 906 951 952 +3 907 906 952 +3 908 907 952 +3 908 952 953 +3 908 953 954 +3 909 908 954 +3 910 909 954 +3 910 954 955 +3 910 955 956 +3 911 910 956 +3 912 911 956 +3 912 956 957 +3 912 957 958 +3 913 912 958 +3 914 913 958 +3 914 958 959 +3 914 959 960 +3 915 914 960 +3 916 915 960 +3 916 960 961 +3 916 961 962 +3 917 916 962 +3 827 917 962 +3 918 737 963 +3 918 963 964 +3 919 918 964 +3 920 919 964 +3 920 964 965 +3 920 965 966 +3 921 920 966 +3 922 921 966 +3 922 966 967 +3 922 967 968 +3 923 922 968 +3 924 923 968 +3 924 968 969 +3 924 969 970 +3 925 924 970 +3 926 925 970 +3 926 970 971 +3 926 971 972 +3 927 926 972 +3 928 927 972 +3 928 972 973 +3 928 973 974 +3 929 928 974 +3 930 929 974 +3 930 974 975 +3 930 975 976 +3 931 930 976 +3 932 931 976 +3 932 976 977 +3 932 977 978 +3 933 932 978 +3 934 933 978 +3 934 978 979 +3 934 979 980 +3 935 934 980 +3 936 935 980 +3 936 980 981 +3 936 981 982 +3 937 936 982 +3 938 937 982 +3 938 982 983 +3 938 983 984 +3 939 938 984 +3 940 939 984 +3 940 984 985 +3 940 985 986 +3 941 940 986 +3 942 941 986 +3 942 986 987 +3 942 987 988 +3 943 942 988 +3 944 943 988 +3 944 988 989 +3 944 989 990 +3 945 944 990 +3 946 945 990 +3 946 990 991 +3 946 991 992 +3 947 946 992 +3 948 947 992 +3 948 992 993 +3 948 993 994 +3 949 948 994 +3 950 949 994 +3 950 994 995 +3 950 995 996 +3 951 950 996 +3 952 951 996 +3 952 996 997 +3 952 997 998 +3 953 952 998 +3 954 953 998 +3 954 998 999 +3 954 999 1000 +3 955 954 1000 +3 956 955 1000 +3 956 1000 1001 +3 956 1001 1002 +3 957 956 1002 +3 958 957 1002 +3 958 1002 1003 +3 958 1003 1004 +3 959 958 1004 +3 960 959 1004 +3 960 1004 1005 +3 960 1005 1006 +3 961 960 1006 +3 962 961 1006 +3 962 1006 1007 +3 962 1007 827 +3 963 737 1008 +3 964 963 1008 +3 964 1008 1009 +3 964 1009 1010 +3 965 964 1010 +3 966 965 1010 +3 966 1010 1011 +3 966 1011 1012 +3 967 966 1012 +3 968 967 1012 +3 968 1012 1013 +3 968 1013 1014 +3 969 968 1014 +3 970 969 1014 +3 970 1014 1015 +3 970 1015 1016 +3 971 970 1016 +3 972 971 1016 +3 972 1016 1017 +3 972 1017 1018 +3 973 972 1018 +3 974 973 1018 +3 974 1018 1019 +3 974 1019 1020 +3 975 974 1020 +3 976 975 1020 +3 976 1020 1021 +3 976 1021 1022 +3 977 976 1022 +3 978 977 1022 +3 978 1022 1023 +3 978 1023 1024 +3 979 978 1024 +3 980 979 1024 +3 980 1024 1025 +3 980 1025 1026 +3 981 980 1026 +3 982 981 1026 +3 982 1026 1027 +3 982 1027 1028 +3 983 982 1028 +3 984 983 1028 +3 984 1028 1029 +3 984 1029 1030 +3 985 984 1030 +3 986 985 1030 +3 986 1030 1031 +3 986 1031 1032 +3 987 986 1032 +3 988 987 1032 +3 988 1032 1033 +3 988 1033 1034 +3 989 988 1034 +3 990 989 1034 +3 990 1034 1035 +3 990 1035 1036 +3 991 990 1036 +3 992 991 1036 +3 992 1036 1037 +3 992 1037 1038 +3 993 992 1038 +3 994 993 1038 +3 994 1038 1039 +3 994 1039 1040 +3 995 994 1040 +3 996 995 1040 +3 996 1040 1041 +3 996 1041 1042 +3 997 996 1042 +3 998 997 1042 +3 998 1042 1043 +3 998 1043 1044 +3 999 998 1044 +3 1000 999 1044 +3 1000 1044 1045 +3 1000 1045 1046 +3 1001 1000 1046 +3 1002 1001 1046 +3 1002 1046 1047 +3 1002 1047 1048 +3 1003 1002 1048 +3 1004 1003 1048 +3 1004 1048 1049 +3 1004 1049 1050 +3 1005 1004 1050 +3 1006 1005 1050 +3 1006 1050 1051 +3 1006 1051 1052 +3 1007 1006 1052 +3 827 1007 1052 +3 1008 737 1053 +3 1008 1053 1054 +3 1009 1008 1054 +3 1010 1009 1054 +3 1010 1054 1055 +3 1010 1055 1056 +3 1011 1010 1056 +3 1012 1011 1056 +3 1012 1056 1057 +3 1012 1057 1058 +3 1013 1012 1058 +3 1014 1013 1058 +3 1014 1058 1059 +3 1014 1059 1060 +3 1015 1014 1060 +3 1016 1015 1060 +3 1016 1060 1061 +3 1016 1061 1062 +3 1017 1016 1062 +3 1018 1017 1062 +3 1018 1062 1063 +3 1018 1063 1064 +3 1019 1018 1064 +3 1020 1019 1064 +3 1020 1064 1065 +3 1020 1065 1066 +3 1021 1020 1066 +3 1022 1021 1066 +3 1022 1066 1067 +3 1022 1067 1068 +3 1023 1022 1068 +3 1024 1023 1068 +3 1024 1068 1069 +3 1024 1069 1070 +3 1025 1024 1070 +3 1026 1025 1070 +3 1026 1070 1071 +3 1026 1071 1072 +3 1027 1026 1072 +3 1028 1027 1072 +3 1028 1072 1073 +3 1028 1073 1074 +3 1029 1028 1074 +3 1030 1029 1074 +3 1030 1074 1075 +3 1030 1075 1076 +3 1031 1030 1076 +3 1032 1031 1076 +3 1032 1076 1077 +3 1032 1077 1078 +3 1033 1032 1078 +3 1034 1033 1078 +3 1034 1078 1079 +3 1034 1079 1080 +3 1035 1034 1080 +3 1036 1035 1080 +3 1036 1080 1081 +3 1036 1081 1082 +3 1037 1036 1082 +3 1038 1037 1082 +3 1038 1082 1083 +3 1038 1083 1084 +3 1039 1038 1084 +3 1040 1039 1084 +3 1040 1084 1085 +3 1040 1085 1086 +3 1041 1040 1086 +3 1042 1041 1086 +3 1042 1086 1087 +3 1042 1087 1088 +3 1043 1042 1088 +3 1044 1043 1088 +3 1044 1088 1089 +3 1044 1089 1090 +3 1045 1044 1090 +3 1046 1045 1090 +3 1046 1090 1091 +3 1046 1091 1092 +3 1047 1046 1092 +3 1048 1047 1092 +3 1048 1092 1093 +3 1048 1093 1094 +3 1049 1048 1094 +3 1050 1049 1094 +3 1050 1094 1095 +3 1050 1095 1096 +3 1051 1050 1096 +3 1052 1051 1096 +3 1052 1096 1097 +3 1052 1097 827 +3 1053 737 736 +3 1054 1053 736 +3 1054 736 740 +3 1054 740 741 +3 1055 1054 741 +3 1056 1055 741 +3 1056 741 744 +3 1056 744 745 +3 1057 1056 745 +3 1058 1057 745 +3 1058 745 748 +3 1058 748 749 +3 1059 1058 749 +3 1060 1059 749 +3 1060 749 752 +3 1060 752 753 +3 1061 1060 753 +3 1062 1061 753 +3 1062 753 756 +3 1062 756 757 +3 1063 1062 757 +3 1064 1063 757 +3 1064 757 760 +3 1064 760 761 +3 1065 1064 761 +3 1066 1065 761 +3 1066 761 764 +3 1066 764 765 +3 1067 1066 765 +3 1068 1067 765 +3 1068 765 768 +3 1068 768 769 +3 1069 1068 769 +3 1070 1069 769 +3 1070 769 772 +3 1070 772 773 +3 1071 1070 773 +3 1072 1071 773 +3 1072 773 776 +3 1072 776 777 +3 1073 1072 777 +3 1074 1073 777 +3 1074 777 780 +3 1074 780 781 +3 1075 1074 781 +3 1076 1075 781 +3 1076 781 784 +3 1076 784 785 +3 1077 1076 785 +3 1078 1077 785 +3 1078 785 788 +3 1078 788 789 +3 1079 1078 789 +3 1080 1079 789 +3 1080 789 792 +3 1080 792 793 +3 1081 1080 793 +3 1082 1081 793 +3 1082 793 796 +3 1082 796 797 +3 1083 1082 797 +3 1084 1083 797 +3 1084 797 800 +3 1084 800 801 +3 1085 1084 801 +3 1086 1085 801 +3 1086 801 804 +3 1086 804 805 +3 1087 1086 805 +3 1088 1087 805 +3 1088 805 808 +3 1088 808 809 +3 1089 1088 809 +3 1090 1089 809 +3 1090 809 812 +3 1090 812 813 +3 1091 1090 813 +3 1092 1091 813 +3 1092 813 816 +3 1092 816 817 +3 1093 1092 817 +3 1094 1093 817 +3 1094 817 820 +3 1094 820 821 +3 1095 1094 821 +3 1096 1095 821 +3 1096 821 824 +3 1096 824 825 +3 1097 1096 825 +3 827 1097 825 +3 1098 1099 1100 +3 1098 1100 1101 +3 1102 1098 1101 +3 1103 1102 1101 +3 1103 1101 1104 +3 1103 1104 1105 +3 1106 1103 1105 +3 1107 1106 1105 +3 1107 1105 1108 +3 1107 1108 1109 +3 1110 1107 1109 +3 1111 1110 1109 +3 1111 1109 1112 +3 1111 1112 1113 +3 1114 1111 1113 +3 1115 1114 1113 +3 1115 1113 1116 +3 1115 1116 1117 +3 1118 1115 1117 +3 1119 1118 1117 +3 1119 1117 1120 +3 1119 1120 1121 +3 1122 1119 1121 +3 1123 1122 1121 +3 1123 1121 1124 +3 1123 1124 1125 +3 1126 1123 1125 +3 1127 1126 1125 +3 1127 1125 1128 +3 1127 1128 1129 +3 1130 1127 1129 +3 1131 1130 1129 +3 1131 1129 1132 +3 1131 1132 1133 +3 1134 1131 1133 +3 1135 1134 1133 +3 1135 1133 1136 +3 1135 1136 1137 +3 1138 1135 1137 +3 1139 1138 1137 +3 1139 1137 1140 +3 1139 1140 1141 +3 1142 1139 1141 +3 1143 1142 1141 +3 1143 1141 1144 +3 1143 1144 1145 +3 1146 1143 1145 +3 1147 1146 1145 +3 1147 1145 1148 +3 1147 1148 1149 +3 1150 1147 1149 +3 1151 1150 1149 +3 1151 1149 1152 +3 1151 1152 1153 +3 1154 1151 1153 +3 1155 1154 1153 +3 1155 1153 1156 +3 1155 1156 1157 +3 1158 1155 1157 +3 1159 1158 1157 +3 1159 1157 1160 +3 1159 1160 1161 +3 1162 1159 1161 +3 1163 1162 1161 +3 1163 1161 1164 +3 1163 1164 1165 +3 1166 1163 1165 +3 1167 1166 1165 +3 1167 1165 1168 +3 1167 1168 1169 +3 1170 1167 1169 +3 1171 1170 1169 +3 1171 1169 1172 +3 1171 1172 1173 +3 1174 1171 1173 +3 1175 1174 1173 +3 1175 1173 1176 +3 1175 1176 1177 +3 1178 1175 1177 +3 1179 1178 1177 +3 1179 1177 1180 +3 1179 1180 1181 +3 1182 1179 1181 +3 1183 1182 1181 +3 1183 1181 1184 +3 1183 1184 1185 +3 1186 1183 1185 +3 1187 1186 1185 +3 1187 1185 1188 +3 1187 1188 1189 +3 1100 1099 1190 +3 1101 1100 1190 +3 1101 1190 1191 +3 1101 1191 1192 +3 1104 1101 1192 +3 1105 1104 1192 +3 1105 1192 1193 +3 1105 1193 1194 +3 1108 1105 1194 +3 1109 1108 1194 +3 1109 1194 1195 +3 1109 1195 1196 +3 1112 1109 1196 +3 1113 1112 1196 +3 1113 1196 1197 +3 1113 1197 1198 +3 1116 1113 1198 +3 1117 1116 1198 +3 1117 1198 1199 +3 1117 1199 1200 +3 1120 1117 1200 +3 1121 1120 1200 +3 1121 1200 1201 +3 1121 1201 1202 +3 1124 1121 1202 +3 1125 1124 1202 +3 1125 1202 1203 +3 1125 1203 1204 +3 1128 1125 1204 +3 1129 1128 1204 +3 1129 1204 1205 +3 1129 1205 1206 +3 1132 1129 1206 +3 1133 1132 1206 +3 1133 1206 1207 +3 1133 1207 1208 +3 1136 1133 1208 +3 1137 1136 1208 +3 1137 1208 1209 +3 1137 1209 1210 +3 1140 1137 1210 +3 1141 1140 1210 +3 1141 1210 1211 +3 1141 1211 1212 +3 1144 1141 1212 +3 1145 1144 1212 +3 1145 1212 1213 +3 1145 1213 1214 +3 1148 1145 1214 +3 1149 1148 1214 +3 1149 1214 1215 +3 1149 1215 1216 +3 1152 1149 1216 +3 1153 1152 1216 +3 1153 1216 1217 +3 1153 1217 1218 +3 1156 1153 1218 +3 1157 1156 1218 +3 1157 1218 1219 +3 1157 1219 1220 +3 1160 1157 1220 +3 1161 1160 1220 +3 1161 1220 1221 +3 1161 1221 1222 +3 1164 1161 1222 +3 1165 1164 1222 +3 1165 1222 1223 +3 1165 1223 1224 +3 1168 1165 1224 +3 1169 1168 1224 +3 1169 1224 1225 +3 1169 1225 1226 +3 1172 1169 1226 +3 1173 1172 1226 +3 1173 1226 1227 +3 1173 1227 1228 +3 1176 1173 1228 +3 1177 1176 1228 +3 1177 1228 1229 +3 1177 1229 1230 +3 1180 1177 1230 +3 1181 1180 1230 +3 1181 1230 1231 +3 1181 1231 1232 +3 1184 1181 1232 +3 1185 1184 1232 +3 1185 1232 1233 +3 1185 1233 1234 +3 1188 1185 1234 +3 1189 1188 1234 +3 1190 1099 1235 +3 1190 1235 1236 +3 1191 1190 1236 +3 1192 1191 1236 +3 1192 1236 1237 +3 1192 1237 1238 +3 1193 1192 1238 +3 1194 1193 1238 +3 1194 1238 1239 +3 1194 1239 1240 +3 1195 1194 1240 +3 1196 1195 1240 +3 1196 1240 1241 +3 1196 1241 1242 +3 1197 1196 1242 +3 1198 1197 1242 +3 1198 1242 1243 +3 1198 1243 1244 +3 1199 1198 1244 +3 1200 1199 1244 +3 1200 1244 1245 +3 1200 1245 1246 +3 1201 1200 1246 +3 1202 1201 1246 +3 1202 1246 1247 +3 1202 1247 1248 +3 1203 1202 1248 +3 1204 1203 1248 +3 1204 1248 1249 +3 1204 1249 1250 +3 1205 1204 1250 +3 1206 1205 1250 +3 1206 1250 1251 +3 1206 1251 1252 +3 1207 1206 1252 +3 1208 1207 1252 +3 1208 1252 1253 +3 1208 1253 1254 +3 1209 1208 1254 +3 1210 1209 1254 +3 1210 1254 1255 +3 1210 1255 1256 +3 1211 1210 1256 +3 1212 1211 1256 +3 1212 1256 1257 +3 1212 1257 1258 +3 1213 1212 1258 +3 1214 1213 1258 +3 1214 1258 1259 +3 1214 1259 1260 +3 1215 1214 1260 +3 1216 1215 1260 +3 1216 1260 1261 +3 1216 1261 1262 +3 1217 1216 1262 +3 1218 1217 1262 +3 1218 1262 1263 +3 1218 1263 1264 +3 1219 1218 1264 +3 1220 1219 1264 +3 1220 1264 1265 +3 1220 1265 1266 +3 1221 1220 1266 +3 1222 1221 1266 +3 1222 1266 1267 +3 1222 1267 1268 +3 1223 1222 1268 +3 1224 1223 1268 +3 1224 1268 1269 +3 1224 1269 1270 +3 1225 1224 1270 +3 1226 1225 1270 +3 1226 1270 1271 +3 1226 1271 1272 +3 1227 1226 1272 +3 1228 1227 1272 +3 1228 1272 1273 +3 1228 1273 1274 +3 1229 1228 1274 +3 1230 1229 1274 +3 1230 1274 1275 +3 1230 1275 1276 +3 1231 1230 1276 +3 1232 1231 1276 +3 1232 1276 1277 +3 1232 1277 1278 +3 1233 1232 1278 +3 1234 1233 1278 +3 1234 1278 1279 +3 1234 1279 1189 +3 1235 1099 1280 +3 1236 1235 1280 +3 1236 1280 1281 +3 1236 1281 1282 +3 1237 1236 1282 +3 1238 1237 1282 +3 1238 1282 1283 +3 1238 1283 1284 +3 1239 1238 1284 +3 1240 1239 1284 +3 1240 1284 1285 +3 1240 1285 1286 +3 1241 1240 1286 +3 1242 1241 1286 +3 1242 1286 1287 +3 1242 1287 1288 +3 1243 1242 1288 +3 1244 1243 1288 +3 1244 1288 1289 +3 1244 1289 1290 +3 1245 1244 1290 +3 1246 1245 1290 +3 1246 1290 1291 +3 1246 1291 1292 +3 1247 1246 1292 +3 1248 1247 1292 +3 1248 1292 1293 +3 1248 1293 1294 +3 1249 1248 1294 +3 1250 1249 1294 +3 1250 1294 1295 +3 1250 1295 1296 +3 1251 1250 1296 +3 1252 1251 1296 +3 1252 1296 1297 +3 1252 1297 1298 +3 1253 1252 1298 +3 1254 1253 1298 +3 1254 1298 1299 +3 1254 1299 1300 +3 1255 1254 1300 +3 1256 1255 1300 +3 1256 1300 1301 +3 1256 1301 1302 +3 1257 1256 1302 +3 1258 1257 1302 +3 1258 1302 1303 +3 1258 1303 1304 +3 1259 1258 1304 +3 1260 1259 1304 +3 1260 1304 1305 +3 1260 1305 1306 +3 1261 1260 1306 +3 1262 1261 1306 +3 1262 1306 1307 +3 1262 1307 1308 +3 1263 1262 1308 +3 1264 1263 1308 +3 1264 1308 1309 +3 1264 1309 1310 +3 1265 1264 1310 +3 1266 1265 1310 +3 1266 1310 1311 +3 1266 1311 1312 +3 1267 1266 1312 +3 1268 1267 1312 +3 1268 1312 1313 +3 1268 1313 1314 +3 1269 1268 1314 +3 1270 1269 1314 +3 1270 1314 1315 +3 1270 1315 1316 +3 1271 1270 1316 +3 1272 1271 1316 +3 1272 1316 1317 +3 1272 1317 1318 +3 1273 1272 1318 +3 1274 1273 1318 +3 1274 1318 1319 +3 1274 1319 1320 +3 1275 1274 1320 +3 1276 1275 1320 +3 1276 1320 1321 +3 1276 1321 1322 +3 1277 1276 1322 +3 1278 1277 1322 +3 1278 1322 1323 +3 1278 1323 1324 +3 1279 1278 1324 +3 1189 1279 1324 +3 1280 1099 1325 +3 1280 1325 1326 +3 1281 1280 1326 +3 1282 1281 1326 +3 1282 1326 1327 +3 1282 1327 1328 +3 1283 1282 1328 +3 1284 1283 1328 +3 1284 1328 1329 +3 1284 1329 1330 +3 1285 1284 1330 +3 1286 1285 1330 +3 1286 1330 1331 +3 1286 1331 1332 +3 1287 1286 1332 +3 1288 1287 1332 +3 1288 1332 1333 +3 1288 1333 1334 +3 1289 1288 1334 +3 1290 1289 1334 +3 1290 1334 1335 +3 1290 1335 1336 +3 1291 1290 1336 +3 1292 1291 1336 +3 1292 1336 1337 +3 1292 1337 1338 +3 1293 1292 1338 +3 1294 1293 1338 +3 1294 1338 1339 +3 1294 1339 1340 +3 1295 1294 1340 +3 1296 1295 1340 +3 1296 1340 1341 +3 1296 1341 1342 +3 1297 1296 1342 +3 1298 1297 1342 +3 1298 1342 1343 +3 1298 1343 1344 +3 1299 1298 1344 +3 1300 1299 1344 +3 1300 1344 1345 +3 1300 1345 1346 +3 1301 1300 1346 +3 1302 1301 1346 +3 1302 1346 1347 +3 1302 1347 1348 +3 1303 1302 1348 +3 1304 1303 1348 +3 1304 1348 1349 +3 1304 1349 1350 +3 1305 1304 1350 +3 1306 1305 1350 +3 1306 1350 1351 +3 1306 1351 1352 +3 1307 1306 1352 +3 1308 1307 1352 +3 1308 1352 1353 +3 1308 1353 1354 +3 1309 1308 1354 +3 1310 1309 1354 +3 1310 1354 1355 +3 1310 1355 1356 +3 1311 1310 1356 +3 1312 1311 1356 +3 1312 1356 1357 +3 1312 1357 1358 +3 1313 1312 1358 +3 1314 1313 1358 +3 1314 1358 1359 +3 1314 1359 1360 +3 1315 1314 1360 +3 1316 1315 1360 +3 1316 1360 1361 +3 1316 1361 1362 +3 1317 1316 1362 +3 1318 1317 1362 +3 1318 1362 1363 +3 1318 1363 1364 +3 1319 1318 1364 +3 1320 1319 1364 +3 1320 1364 1365 +3 1320 1365 1366 +3 1321 1320 1366 +3 1322 1321 1366 +3 1322 1366 1367 +3 1322 1367 1368 +3 1323 1322 1368 +3 1324 1323 1368 +3 1324 1368 1369 +3 1324 1369 1189 +3 1325 1099 1370 +3 1326 1325 1370 +3 1326 1370 1371 +3 1326 1371 1372 +3 1327 1326 1372 +3 1328 1327 1372 +3 1328 1372 1373 +3 1328 1373 1374 +3 1329 1328 1374 +3 1330 1329 1374 +3 1330 1374 1375 +3 1330 1375 1376 +3 1331 1330 1376 +3 1332 1331 1376 +3 1332 1376 1377 +3 1332 1377 1378 +3 1333 1332 1378 +3 1334 1333 1378 +3 1334 1378 1379 +3 1334 1379 1380 +3 1335 1334 1380 +3 1336 1335 1380 +3 1336 1380 1381 +3 1336 1381 1382 +3 1337 1336 1382 +3 1338 1337 1382 +3 1338 1382 1383 +3 1338 1383 1384 +3 1339 1338 1384 +3 1340 1339 1384 +3 1340 1384 1385 +3 1340 1385 1386 +3 1341 1340 1386 +3 1342 1341 1386 +3 1342 1386 1387 +3 1342 1387 1388 +3 1343 1342 1388 +3 1344 1343 1388 +3 1344 1388 1389 +3 1344 1389 1390 +3 1345 1344 1390 +3 1346 1345 1390 +3 1346 1390 1391 +3 1346 1391 1392 +3 1347 1346 1392 +3 1348 1347 1392 +3 1348 1392 1393 +3 1348 1393 1394 +3 1349 1348 1394 +3 1350 1349 1394 +3 1350 1394 1395 +3 1350 1395 1396 +3 1351 1350 1396 +3 1352 1351 1396 +3 1352 1396 1397 +3 1352 1397 1398 +3 1353 1352 1398 +3 1354 1353 1398 +3 1354 1398 1399 +3 1354 1399 1400 +3 1355 1354 1400 +3 1356 1355 1400 +3 1356 1400 1401 +3 1356 1401 1402 +3 1357 1356 1402 +3 1358 1357 1402 +3 1358 1402 1403 +3 1358 1403 1404 +3 1359 1358 1404 +3 1360 1359 1404 +3 1360 1404 1405 +3 1360 1405 1406 +3 1361 1360 1406 +3 1362 1361 1406 +3 1362 1406 1407 +3 1362 1407 1408 +3 1363 1362 1408 +3 1364 1363 1408 +3 1364 1408 1409 +3 1364 1409 1410 +3 1365 1364 1410 +3 1366 1365 1410 +3 1366 1410 1411 +3 1366 1411 1412 +3 1367 1366 1412 +3 1368 1367 1412 +3 1368 1412 1413 +3 1368 1413 1414 +3 1369 1368 1414 +3 1189 1369 1414 +3 1370 1099 1415 +3 1370 1415 1416 +3 1371 1370 1416 +3 1372 1371 1416 +3 1372 1416 1417 +3 1372 1417 1418 +3 1373 1372 1418 +3 1374 1373 1418 +3 1374 1418 1419 +3 1374 1419 1420 +3 1375 1374 1420 +3 1376 1375 1420 +3 1376 1420 1421 +3 1376 1421 1422 +3 1377 1376 1422 +3 1378 1377 1422 +3 1378 1422 1423 +3 1378 1423 1424 +3 1379 1378 1424 +3 1380 1379 1424 +3 1380 1424 1425 +3 1380 1425 1426 +3 1381 1380 1426 +3 1382 1381 1426 +3 1382 1426 1427 +3 1382 1427 1428 +3 1383 1382 1428 +3 1384 1383 1428 +3 1384 1428 1429 +3 1384 1429 1430 +3 1385 1384 1430 +3 1386 1385 1430 +3 1386 1430 1431 +3 1386 1431 1432 +3 1387 1386 1432 +3 1388 1387 1432 +3 1388 1432 1433 +3 1388 1433 1434 +3 1389 1388 1434 +3 1390 1389 1434 +3 1390 1434 1435 +3 1390 1435 1436 +3 1391 1390 1436 +3 1392 1391 1436 +3 1392 1436 1437 +3 1392 1437 1438 +3 1393 1392 1438 +3 1394 1393 1438 +3 1394 1438 1439 +3 1394 1439 1440 +3 1395 1394 1440 +3 1396 1395 1440 +3 1396 1440 1441 +3 1396 1441 1442 +3 1397 1396 1442 +3 1398 1397 1442 +3 1398 1442 1443 +3 1398 1443 1444 +3 1399 1398 1444 +3 1400 1399 1444 +3 1400 1444 1445 +3 1400 1445 1446 +3 1401 1400 1446 +3 1402 1401 1446 +3 1402 1446 1447 +3 1402 1447 1448 +3 1403 1402 1448 +3 1404 1403 1448 +3 1404 1448 1449 +3 1404 1449 1450 +3 1405 1404 1450 +3 1406 1405 1450 +3 1406 1450 1451 +3 1406 1451 1452 +3 1407 1406 1452 +3 1408 1407 1452 +3 1408 1452 1453 +3 1408 1453 1454 +3 1409 1408 1454 +3 1410 1409 1454 +3 1410 1454 1455 +3 1410 1455 1456 +3 1411 1410 1456 +3 1412 1411 1456 +3 1412 1456 1457 +3 1412 1457 1458 +3 1413 1412 1458 +3 1414 1413 1458 +3 1414 1458 1459 +3 1414 1459 1189 +3 1415 1099 1098 +3 1416 1415 1098 +3 1416 1098 1102 +3 1416 1102 1103 +3 1417 1416 1103 +3 1418 1417 1103 +3 1418 1103 1106 +3 1418 1106 1107 +3 1419 1418 1107 +3 1420 1419 1107 +3 1420 1107 1110 +3 1420 1110 1111 +3 1421 1420 1111 +3 1422 1421 1111 +3 1422 1111 1114 +3 1422 1114 1115 +3 1423 1422 1115 +3 1424 1423 1115 +3 1424 1115 1118 +3 1424 1118 1119 +3 1425 1424 1119 +3 1426 1425 1119 +3 1426 1119 1122 +3 1426 1122 1123 +3 1427 1426 1123 +3 1428 1427 1123 +3 1428 1123 1126 +3 1428 1126 1127 +3 1429 1428 1127 +3 1430 1429 1127 +3 1430 1127 1130 +3 1430 1130 1131 +3 1431 1430 1131 +3 1432 1431 1131 +3 1432 1131 1134 +3 1432 1134 1135 +3 1433 1432 1135 +3 1434 1433 1135 +3 1434 1135 1138 +3 1434 1138 1139 +3 1435 1434 1139 +3 1436 1435 1139 +3 1436 1139 1142 +3 1436 1142 1143 +3 1437 1436 1143 +3 1438 1437 1143 +3 1438 1143 1146 +3 1438 1146 1147 +3 1439 1438 1147 +3 1440 1439 1147 +3 1440 1147 1150 +3 1440 1150 1151 +3 1441 1440 1151 +3 1442 1441 1151 +3 1442 1151 1154 +3 1442 1154 1155 +3 1443 1442 1155 +3 1444 1443 1155 +3 1444 1155 1158 +3 1444 1158 1159 +3 1445 1444 1159 +3 1446 1445 1159 +3 1446 1159 1162 +3 1446 1162 1163 +3 1447 1446 1163 +3 1448 1447 1163 +3 1448 1163 1166 +3 1448 1166 1167 +3 1449 1448 1167 +3 1450 1449 1167 +3 1450 1167 1170 +3 1450 1170 1171 +3 1451 1450 1171 +3 1452 1451 1171 +3 1452 1171 1174 +3 1452 1174 1175 +3 1453 1452 1175 +3 1454 1453 1175 +3 1454 1175 1178 +3 1454 1178 1179 +3 1455 1454 1179 +3 1456 1455 1179 +3 1456 1179 1182 +3 1456 1182 1183 +3 1457 1456 1183 +3 1458 1457 1183 +3 1458 1183 1186 +3 1458 1186 1187 +3 1459 1458 1187 +3 1189 1459 1187 +3 1460 1461 1462 +3 1460 1462 1463 +3 1464 1460 1463 +3 1465 1464 1463 +3 1465 1463 1466 +3 1465 1466 1467 +3 1468 1465 1467 +3 1469 1468 1467 +3 1469 1467 1470 +3 1469 1470 1471 +3 1472 1469 1471 +3 1473 1472 1471 +3 1473 1471 1474 +3 1473 1474 1475 +3 1476 1473 1475 +3 1477 1476 1475 +3 1477 1475 1478 +3 1477 1478 1479 +3 1480 1477 1479 +3 1481 1480 1479 +3 1481 1479 1482 +3 1481 1482 1483 +3 1484 1481 1483 +3 1485 1484 1483 +3 1485 1483 1486 +3 1485 1486 1487 +3 1488 1485 1487 +3 1489 1488 1487 +3 1489 1487 1490 +3 1489 1490 1491 +3 1492 1489 1491 +3 1493 1492 1491 +3 1493 1491 1494 +3 1493 1494 1495 +3 1496 1493 1495 +3 1497 1496 1495 +3 1497 1495 1498 +3 1497 1498 1499 +3 1500 1497 1499 +3 1501 1500 1499 +3 1501 1499 1502 +3 1501 1502 1503 +3 1504 1501 1503 +3 1505 1504 1503 +3 1505 1503 1506 +3 1505 1506 1507 +3 1508 1505 1507 +3 1509 1508 1507 +3 1509 1507 1510 +3 1509 1510 1511 +3 1512 1509 1511 +3 1513 1512 1511 +3 1513 1511 1514 +3 1513 1514 1515 +3 1516 1513 1515 +3 1517 1516 1515 +3 1517 1515 1518 +3 1517 1518 1519 +3 1520 1517 1519 +3 1521 1520 1519 +3 1521 1519 1522 +3 1521 1522 1523 +3 1524 1521 1523 +3 1525 1524 1523 +3 1525 1523 1526 +3 1525 1526 1527 +3 1528 1525 1527 +3 1529 1528 1527 +3 1529 1527 1530 +3 1529 1530 1531 +3 1532 1529 1531 +3 1533 1532 1531 +3 1533 1531 1534 +3 1533 1534 1535 +3 1536 1533 1535 +3 1537 1536 1535 +3 1537 1535 1538 +3 1537 1538 1539 +3 1540 1537 1539 +3 1541 1540 1539 +3 1541 1539 1542 +3 1541 1542 1543 +3 1544 1541 1543 +3 1545 1544 1543 +3 1545 1543 1546 +3 1545 1546 1547 +3 1548 1545 1547 +3 1549 1548 1547 +3 1549 1547 1550 +3 1549 1550 1189 +3 1462 1461 1551 +3 1463 1462 1551 +3 1463 1551 1552 +3 1463 1552 1553 +3 1466 1463 1553 +3 1467 1466 1553 +3 1467 1553 1554 +3 1467 1554 1555 +3 1470 1467 1555 +3 1471 1470 1555 +3 1471 1555 1556 +3 1471 1556 1557 +3 1474 1471 1557 +3 1475 1474 1557 +3 1475 1557 1558 +3 1475 1558 1559 +3 1478 1475 1559 +3 1479 1478 1559 +3 1479 1559 1560 +3 1479 1560 1561 +3 1482 1479 1561 +3 1483 1482 1561 +3 1483 1561 1562 +3 1483 1562 1563 +3 1486 1483 1563 +3 1487 1486 1563 +3 1487 1563 1564 +3 1487 1564 1565 +3 1490 1487 1565 +3 1491 1490 1565 +3 1491 1565 1566 +3 1491 1566 1567 +3 1494 1491 1567 +3 1495 1494 1567 +3 1495 1567 1568 +3 1495 1568 1569 +3 1498 1495 1569 +3 1499 1498 1569 +3 1499 1569 1570 +3 1499 1570 1571 +3 1502 1499 1571 +3 1503 1502 1571 +3 1503 1571 1572 +3 1503 1572 1573 +3 1506 1503 1573 +3 1507 1506 1573 +3 1507 1573 1574 +3 1507 1574 1575 +3 1510 1507 1575 +3 1511 1510 1575 +3 1511 1575 1576 +3 1511 1576 1577 +3 1514 1511 1577 +3 1515 1514 1577 +3 1515 1577 1578 +3 1515 1578 1579 +3 1518 1515 1579 +3 1519 1518 1579 +3 1519 1579 1580 +3 1519 1580 1581 +3 1522 1519 1581 +3 1523 1522 1581 +3 1523 1581 1582 +3 1523 1582 1583 +3 1526 1523 1583 +3 1527 1526 1583 +3 1527 1583 1584 +3 1527 1584 1585 +3 1530 1527 1585 +3 1531 1530 1585 +3 1531 1585 1586 +3 1531 1586 1587 +3 1534 1531 1587 +3 1535 1534 1587 +3 1535 1587 1588 +3 1535 1588 1589 +3 1538 1535 1589 +3 1539 1538 1589 +3 1539 1589 1590 +3 1539 1590 1591 +3 1542 1539 1591 +3 1543 1542 1591 +3 1543 1591 1592 +3 1543 1592 1593 +3 1546 1543 1593 +3 1547 1546 1593 +3 1547 1593 1594 +3 1547 1594 1595 +3 1550 1547 1595 +3 1189 1550 1595 +3 1551 1461 1596 +3 1551 1596 1597 +3 1552 1551 1597 +3 1553 1552 1597 +3 1553 1597 1598 +3 1553 1598 1599 +3 1554 1553 1599 +3 1555 1554 1599 +3 1555 1599 1600 +3 1555 1600 1601 +3 1556 1555 1601 +3 1557 1556 1601 +3 1557 1601 1602 +3 1557 1602 1603 +3 1558 1557 1603 +3 1559 1558 1603 +3 1559 1603 1604 +3 1559 1604 1605 +3 1560 1559 1605 +3 1561 1560 1605 +3 1561 1605 1606 +3 1561 1606 1607 +3 1562 1561 1607 +3 1563 1562 1607 +3 1563 1607 1608 +3 1563 1608 1609 +3 1564 1563 1609 +3 1565 1564 1609 +3 1565 1609 1610 +3 1565 1610 1611 +3 1566 1565 1611 +3 1567 1566 1611 +3 1567 1611 1612 +3 1567 1612 1613 +3 1568 1567 1613 +3 1569 1568 1613 +3 1569 1613 1614 +3 1569 1614 1615 +3 1570 1569 1615 +3 1571 1570 1615 +3 1571 1615 1616 +3 1571 1616 1617 +3 1572 1571 1617 +3 1573 1572 1617 +3 1573 1617 1618 +3 1573 1618 1619 +3 1574 1573 1619 +3 1575 1574 1619 +3 1575 1619 1620 +3 1575 1620 1621 +3 1576 1575 1621 +3 1577 1576 1621 +3 1577 1621 1622 +3 1577 1622 1623 +3 1578 1577 1623 +3 1579 1578 1623 +3 1579 1623 1624 +3 1579 1624 1625 +3 1580 1579 1625 +3 1581 1580 1625 +3 1581 1625 1626 +3 1581 1626 1627 +3 1582 1581 1627 +3 1583 1582 1627 +3 1583 1627 1628 +3 1583 1628 1629 +3 1584 1583 1629 +3 1585 1584 1629 +3 1585 1629 1630 +3 1585 1630 1631 +3 1586 1585 1631 +3 1587 1586 1631 +3 1587 1631 1632 +3 1587 1632 1633 +3 1588 1587 1633 +3 1589 1588 1633 +3 1589 1633 1634 +3 1589 1634 1635 +3 1590 1589 1635 +3 1591 1590 1635 +3 1591 1635 1636 +3 1591 1636 1637 +3 1592 1591 1637 +3 1593 1592 1637 +3 1593 1637 1638 +3 1593 1638 1639 +3 1594 1593 1639 +3 1595 1594 1639 +3 1595 1639 1640 +3 1595 1640 1189 +3 1596 1461 1641 +3 1597 1596 1641 +3 1597 1641 1642 +3 1597 1642 1643 +3 1598 1597 1643 +3 1599 1598 1643 +3 1599 1643 1644 +3 1599 1644 1645 +3 1600 1599 1645 +3 1601 1600 1645 +3 1601 1645 1646 +3 1601 1646 1647 +3 1602 1601 1647 +3 1603 1602 1647 +3 1603 1647 1648 +3 1603 1648 1649 +3 1604 1603 1649 +3 1605 1604 1649 +3 1605 1649 1650 +3 1605 1650 1651 +3 1606 1605 1651 +3 1607 1606 1651 +3 1607 1651 1652 +3 1607 1652 1653 +3 1608 1607 1653 +3 1609 1608 1653 +3 1609 1653 1654 +3 1609 1654 1655 +3 1610 1609 1655 +3 1611 1610 1655 +3 1611 1655 1656 +3 1611 1656 1657 +3 1612 1611 1657 +3 1613 1612 1657 +3 1613 1657 1658 +3 1613 1658 1659 +3 1614 1613 1659 +3 1615 1614 1659 +3 1615 1659 1660 +3 1615 1660 1661 +3 1616 1615 1661 +3 1617 1616 1661 +3 1617 1661 1662 +3 1617 1662 1663 +3 1618 1617 1663 +3 1619 1618 1663 +3 1619 1663 1664 +3 1619 1664 1665 +3 1620 1619 1665 +3 1621 1620 1665 +3 1621 1665 1666 +3 1621 1666 1667 +3 1622 1621 1667 +3 1623 1622 1667 +3 1623 1667 1668 +3 1623 1668 1669 +3 1624 1623 1669 +3 1625 1624 1669 +3 1625 1669 1670 +3 1625 1670 1671 +3 1626 1625 1671 +3 1627 1626 1671 +3 1627 1671 1672 +3 1627 1672 1673 +3 1628 1627 1673 +3 1629 1628 1673 +3 1629 1673 1674 +3 1629 1674 1675 +3 1630 1629 1675 +3 1631 1630 1675 +3 1631 1675 1676 +3 1631 1676 1677 +3 1632 1631 1677 +3 1633 1632 1677 +3 1633 1677 1678 +3 1633 1678 1679 +3 1634 1633 1679 +3 1635 1634 1679 +3 1635 1679 1680 +3 1635 1680 1681 +3 1636 1635 1681 +3 1637 1636 1681 +3 1637 1681 1682 +3 1637 1682 1683 +3 1638 1637 1683 +3 1639 1638 1683 +3 1639 1683 1684 +3 1639 1684 1685 +3 1640 1639 1685 +3 1189 1640 1685 +3 1641 1461 1686 +3 1641 1686 1687 +3 1642 1641 1687 +3 1643 1642 1687 +3 1643 1687 1688 +3 1643 1688 1689 +3 1644 1643 1689 +3 1645 1644 1689 +3 1645 1689 1690 +3 1645 1690 1691 +3 1646 1645 1691 +3 1647 1646 1691 +3 1647 1691 1692 +3 1647 1692 1693 +3 1648 1647 1693 +3 1649 1648 1693 +3 1649 1693 1694 +3 1649 1694 1695 +3 1650 1649 1695 +3 1651 1650 1695 +3 1651 1695 1696 +3 1651 1696 1697 +3 1652 1651 1697 +3 1653 1652 1697 +3 1653 1697 1698 +3 1653 1698 1699 +3 1654 1653 1699 +3 1655 1654 1699 +3 1655 1699 1700 +3 1655 1700 1701 +3 1656 1655 1701 +3 1657 1656 1701 +3 1657 1701 1702 +3 1657 1702 1703 +3 1658 1657 1703 +3 1659 1658 1703 +3 1659 1703 1704 +3 1659 1704 1705 +3 1660 1659 1705 +3 1661 1660 1705 +3 1661 1705 1706 +3 1661 1706 1707 +3 1662 1661 1707 +3 1663 1662 1707 +3 1663 1707 1708 +3 1663 1708 1709 +3 1664 1663 1709 +3 1665 1664 1709 +3 1665 1709 1710 +3 1665 1710 1711 +3 1666 1665 1711 +3 1667 1666 1711 +3 1667 1711 1712 +3 1667 1712 1713 +3 1668 1667 1713 +3 1669 1668 1713 +3 1669 1713 1714 +3 1669 1714 1715 +3 1670 1669 1715 +3 1671 1670 1715 +3 1671 1715 1716 +3 1671 1716 1717 +3 1672 1671 1717 +3 1673 1672 1717 +3 1673 1717 1718 +3 1673 1718 1719 +3 1674 1673 1719 +3 1675 1674 1719 +3 1675 1719 1720 +3 1675 1720 1721 +3 1676 1675 1721 +3 1677 1676 1721 +3 1677 1721 1722 +3 1677 1722 1723 +3 1678 1677 1723 +3 1679 1678 1723 +3 1679 1723 1724 +3 1679 1724 1725 +3 1680 1679 1725 +3 1681 1680 1725 +3 1681 1725 1726 +3 1681 1726 1727 +3 1682 1681 1727 +3 1683 1682 1727 +3 1683 1727 1728 +3 1683 1728 1729 +3 1684 1683 1729 +3 1685 1684 1729 +3 1685 1729 1730 +3 1685 1730 1189 +3 1686 1461 1731 +3 1687 1686 1731 +3 1687 1731 1732 +3 1687 1732 1733 +3 1688 1687 1733 +3 1689 1688 1733 +3 1689 1733 1734 +3 1689 1734 1735 +3 1690 1689 1735 +3 1691 1690 1735 +3 1691 1735 1736 +3 1691 1736 1737 +3 1692 1691 1737 +3 1693 1692 1737 +3 1693 1737 1738 +3 1693 1738 1739 +3 1694 1693 1739 +3 1695 1694 1739 +3 1695 1739 1740 +3 1695 1740 1741 +3 1696 1695 1741 +3 1697 1696 1741 +3 1697 1741 1742 +3 1697 1742 1743 +3 1698 1697 1743 +3 1699 1698 1743 +3 1699 1743 1744 +3 1699 1744 1745 +3 1700 1699 1745 +3 1701 1700 1745 +3 1701 1745 1746 +3 1701 1746 1747 +3 1702 1701 1747 +3 1703 1702 1747 +3 1703 1747 1748 +3 1703 1748 1749 +3 1704 1703 1749 +3 1705 1704 1749 +3 1705 1749 1750 +3 1705 1750 1751 +3 1706 1705 1751 +3 1707 1706 1751 +3 1707 1751 1752 +3 1707 1752 1753 +3 1708 1707 1753 +3 1709 1708 1753 +3 1709 1753 1754 +3 1709 1754 1755 +3 1710 1709 1755 +3 1711 1710 1755 +3 1711 1755 1756 +3 1711 1756 1757 +3 1712 1711 1757 +3 1713 1712 1757 +3 1713 1757 1758 +3 1713 1758 1759 +3 1714 1713 1759 +3 1715 1714 1759 +3 1715 1759 1760 +3 1715 1760 1761 +3 1716 1715 1761 +3 1717 1716 1761 +3 1717 1761 1762 +3 1717 1762 1763 +3 1718 1717 1763 +3 1719 1718 1763 +3 1719 1763 1764 +3 1719 1764 1765 +3 1720 1719 1765 +3 1721 1720 1765 +3 1721 1765 1766 +3 1721 1766 1767 +3 1722 1721 1767 +3 1723 1722 1767 +3 1723 1767 1768 +3 1723 1768 1769 +3 1724 1723 1769 +3 1725 1724 1769 +3 1725 1769 1770 +3 1725 1770 1771 +3 1726 1725 1771 +3 1727 1726 1771 +3 1727 1771 1772 +3 1727 1772 1773 +3 1728 1727 1773 +3 1729 1728 1773 +3 1729 1773 1774 +3 1729 1774 1775 +3 1730 1729 1775 +3 1189 1730 1775 +3 1731 1461 1776 +3 1731 1776 1777 +3 1732 1731 1777 +3 1733 1732 1777 +3 1733 1777 1778 +3 1733 1778 1779 +3 1734 1733 1779 +3 1735 1734 1779 +3 1735 1779 1780 +3 1735 1780 1781 +3 1736 1735 1781 +3 1737 1736 1781 +3 1737 1781 1782 +3 1737 1782 1783 +3 1738 1737 1783 +3 1739 1738 1783 +3 1739 1783 1784 +3 1739 1784 1785 +3 1740 1739 1785 +3 1741 1740 1785 +3 1741 1785 1786 +3 1741 1786 1787 +3 1742 1741 1787 +3 1743 1742 1787 +3 1743 1787 1788 +3 1743 1788 1789 +3 1744 1743 1789 +3 1745 1744 1789 +3 1745 1789 1790 +3 1745 1790 1791 +3 1746 1745 1791 +3 1747 1746 1791 +3 1747 1791 1792 +3 1747 1792 1793 +3 1748 1747 1793 +3 1749 1748 1793 +3 1749 1793 1794 +3 1749 1794 1795 +3 1750 1749 1795 +3 1751 1750 1795 +3 1751 1795 1796 +3 1751 1796 1797 +3 1752 1751 1797 +3 1753 1752 1797 +3 1753 1797 1798 +3 1753 1798 1799 +3 1754 1753 1799 +3 1755 1754 1799 +3 1755 1799 1800 +3 1755 1800 1801 +3 1756 1755 1801 +3 1757 1756 1801 +3 1757 1801 1802 +3 1757 1802 1803 +3 1758 1757 1803 +3 1759 1758 1803 +3 1759 1803 1804 +3 1759 1804 1805 +3 1760 1759 1805 +3 1761 1760 1805 +3 1761 1805 1806 +3 1761 1806 1807 +3 1762 1761 1807 +3 1763 1762 1807 +3 1763 1807 1808 +3 1763 1808 1809 +3 1764 1763 1809 +3 1765 1764 1809 +3 1765 1809 1810 +3 1765 1810 1811 +3 1766 1765 1811 +3 1767 1766 1811 +3 1767 1811 1812 +3 1767 1812 1813 +3 1768 1767 1813 +3 1769 1768 1813 +3 1769 1813 1814 +3 1769 1814 1815 +3 1770 1769 1815 +3 1771 1770 1815 +3 1771 1815 1816 +3 1771 1816 1817 +3 1772 1771 1817 +3 1773 1772 1817 +3 1773 1817 1818 +3 1773 1818 1819 +3 1774 1773 1819 +3 1775 1774 1819 +3 1775 1819 1820 +3 1775 1820 1189 +3 1776 1461 1460 +3 1777 1776 1460 +3 1777 1460 1464 +3 1777 1464 1465 +3 1778 1777 1465 +3 1779 1778 1465 +3 1779 1465 1468 +3 1779 1468 1469 +3 1780 1779 1469 +3 1781 1780 1469 +3 1781 1469 1472 +3 1781 1472 1473 +3 1782 1781 1473 +3 1783 1782 1473 +3 1783 1473 1476 +3 1783 1476 1477 +3 1784 1783 1477 +3 1785 1784 1477 +3 1785 1477 1480 +3 1785 1480 1481 +3 1786 1785 1481 +3 1787 1786 1481 +3 1787 1481 1484 +3 1787 1484 1485 +3 1788 1787 1485 +3 1789 1788 1485 +3 1789 1485 1488 +3 1789 1488 1489 +3 1790 1789 1489 +3 1791 1790 1489 +3 1791 1489 1492 +3 1791 1492 1493 +3 1792 1791 1493 +3 1793 1792 1493 +3 1793 1493 1496 +3 1793 1496 1497 +3 1794 1793 1497 +3 1795 1794 1497 +3 1795 1497 1500 +3 1795 1500 1501 +3 1796 1795 1501 +3 1797 1796 1501 +3 1797 1501 1504 +3 1797 1504 1505 +3 1798 1797 1505 +3 1799 1798 1505 +3 1799 1505 1508 +3 1799 1508 1509 +3 1800 1799 1509 +3 1801 1800 1509 +3 1801 1509 1512 +3 1801 1512 1513 +3 1802 1801 1513 +3 1803 1802 1513 +3 1803 1513 1516 +3 1803 1516 1517 +3 1804 1803 1517 +3 1805 1804 1517 +3 1805 1517 1520 +3 1805 1520 1521 +3 1806 1805 1521 +3 1807 1806 1521 +3 1807 1521 1524 +3 1807 1524 1525 +3 1808 1807 1525 +3 1809 1808 1525 +3 1809 1525 1528 +3 1809 1528 1529 +3 1810 1809 1529 +3 1811 1810 1529 +3 1811 1529 1532 +3 1811 1532 1533 +3 1812 1811 1533 +3 1813 1812 1533 +3 1813 1533 1536 +3 1813 1536 1537 +3 1814 1813 1537 +3 1815 1814 1537 +3 1815 1537 1540 +3 1815 1540 1541 +3 1816 1815 1541 +3 1817 1816 1541 +3 1817 1541 1544 +3 1817 1544 1545 +3 1818 1817 1545 +3 1819 1818 1545 +3 1819 1545 1548 +3 1819 1548 1549 +3 1820 1819 1549 +3 1189 1820 1549 +3 1821 1822 1823 +3 1821 1823 1824 +3 1825 1821 1824 +3 1826 1825 1824 +3 1826 1824 1827 +3 1826 1827 1828 +3 1829 1826 1828 +3 1830 1829 1828 +3 1830 1828 1831 +3 1830 1831 1832 +3 1833 1830 1832 +3 1834 1833 1832 +3 1834 1832 1835 +3 1834 1835 1836 +3 1837 1834 1836 +3 1838 1837 1836 +3 1838 1836 1839 +3 1838 1839 1840 +3 1841 1838 1840 +3 1842 1841 1840 +3 1842 1840 1843 +3 1842 1843 1844 +3 1845 1842 1844 +3 1846 1845 1844 +3 1846 1844 1847 +3 1846 1847 1848 +3 1849 1846 1848 +3 1850 1849 1848 +3 1850 1848 1851 +3 1850 1851 1852 +3 1853 1850 1852 +3 1854 1853 1852 +3 1854 1852 1855 +3 1854 1855 1856 +3 1857 1854 1856 +3 1858 1857 1856 +3 1858 1856 1859 +3 1858 1859 1860 +3 1861 1858 1860 +3 1862 1861 1860 +3 1862 1860 1863 +3 1862 1863 1864 +3 1865 1862 1864 +3 1866 1865 1864 +3 1866 1864 1867 +3 1866 1867 1868 +3 1869 1866 1868 +3 1870 1869 1868 +3 1870 1868 1871 +3 1870 1871 1872 +3 1873 1870 1872 +3 1874 1873 1872 +3 1874 1872 1875 +3 1874 1875 1876 +3 1877 1874 1876 +3 1878 1877 1876 +3 1878 1876 1879 +3 1878 1879 1880 +3 1881 1878 1880 +3 1882 1881 1880 +3 1882 1880 1883 +3 1882 1883 1884 +3 1885 1882 1884 +3 1886 1885 1884 +3 1886 1884 1887 +3 1886 1887 1888 +3 1889 1886 1888 +3 1890 1889 1888 +3 1890 1888 1891 +3 1890 1891 1892 +3 1893 1890 1892 +3 1894 1893 1892 +3 1894 1892 1895 +3 1894 1895 1896 +3 1897 1894 1896 +3 1898 1897 1896 +3 1898 1896 1899 +3 1898 1899 1900 +3 1901 1898 1900 +3 1902 1901 1900 +3 1902 1900 1903 +3 1902 1903 1904 +3 1905 1902 1904 +3 1906 1905 1904 +3 1906 1904 1907 +3 1906 1907 1908 +3 1909 1906 1908 +3 1910 1909 1908 +3 1910 1908 1911 +3 1910 1911 1912 +3 1823 1822 1913 +3 1824 1823 1913 +3 1824 1913 1914 +3 1824 1914 1915 +3 1827 1824 1915 +3 1828 1827 1915 +3 1828 1915 1916 +3 1828 1916 1917 +3 1831 1828 1917 +3 1832 1831 1917 +3 1832 1917 1918 +3 1832 1918 1919 +3 1835 1832 1919 +3 1836 1835 1919 +3 1836 1919 1920 +3 1836 1920 1921 +3 1839 1836 1921 +3 1840 1839 1921 +3 1840 1921 1922 +3 1840 1922 1923 +3 1843 1840 1923 +3 1844 1843 1923 +3 1844 1923 1924 +3 1844 1924 1925 +3 1847 1844 1925 +3 1848 1847 1925 +3 1848 1925 1926 +3 1848 1926 1927 +3 1851 1848 1927 +3 1852 1851 1927 +3 1852 1927 1928 +3 1852 1928 1929 +3 1855 1852 1929 +3 1856 1855 1929 +3 1856 1929 1930 +3 1856 1930 1931 +3 1859 1856 1931 +3 1860 1859 1931 +3 1860 1931 1932 +3 1860 1932 1933 +3 1863 1860 1933 +3 1864 1863 1933 +3 1864 1933 1934 +3 1864 1934 1935 +3 1867 1864 1935 +3 1868 1867 1935 +3 1868 1935 1936 +3 1868 1936 1937 +3 1871 1868 1937 +3 1872 1871 1937 +3 1872 1937 1938 +3 1872 1938 1939 +3 1875 1872 1939 +3 1876 1875 1939 +3 1876 1939 1940 +3 1876 1940 1941 +3 1879 1876 1941 +3 1880 1879 1941 +3 1880 1941 1942 +3 1880 1942 1943 +3 1883 1880 1943 +3 1884 1883 1943 +3 1884 1943 1944 +3 1884 1944 1945 +3 1887 1884 1945 +3 1888 1887 1945 +3 1888 1945 1946 +3 1888 1946 1947 +3 1891 1888 1947 +3 1892 1891 1947 +3 1892 1947 1948 +3 1892 1948 1949 +3 1895 1892 1949 +3 1896 1895 1949 +3 1896 1949 1950 +3 1896 1950 1951 +3 1899 1896 1951 +3 1900 1899 1951 +3 1900 1951 1952 +3 1900 1952 1953 +3 1903 1900 1953 +3 1904 1903 1953 +3 1904 1953 1954 +3 1904 1954 1955 +3 1907 1904 1955 +3 1908 1907 1955 +3 1908 1955 1956 +3 1908 1956 1957 +3 1911 1908 1957 +3 1912 1911 1957 +3 1913 1822 1958 +3 1913 1958 1959 +3 1914 1913 1959 +3 1915 1914 1959 +3 1915 1959 1960 +3 1915 1960 1961 +3 1916 1915 1961 +3 1917 1916 1961 +3 1917 1961 1962 +3 1917 1962 1963 +3 1918 1917 1963 +3 1919 1918 1963 +3 1919 1963 1964 +3 1919 1964 1965 +3 1920 1919 1965 +3 1921 1920 1965 +3 1921 1965 1966 +3 1921 1966 1967 +3 1922 1921 1967 +3 1923 1922 1967 +3 1923 1967 1968 +3 1923 1968 1969 +3 1924 1923 1969 +3 1925 1924 1969 +3 1925 1969 1970 +3 1925 1970 1971 +3 1926 1925 1971 +3 1927 1926 1971 +3 1927 1971 1972 +3 1927 1972 1973 +3 1928 1927 1973 +3 1929 1928 1973 +3 1929 1973 1974 +3 1929 1974 1975 +3 1930 1929 1975 +3 1931 1930 1975 +3 1931 1975 1976 +3 1931 1976 1977 +3 1932 1931 1977 +3 1933 1932 1977 +3 1933 1977 1978 +3 1933 1978 1979 +3 1934 1933 1979 +3 1935 1934 1979 +3 1935 1979 1980 +3 1935 1980 1981 +3 1936 1935 1981 +3 1937 1936 1981 +3 1937 1981 1982 +3 1937 1982 1983 +3 1938 1937 1983 +3 1939 1938 1983 +3 1939 1983 1984 +3 1939 1984 1985 +3 1940 1939 1985 +3 1941 1940 1985 +3 1941 1985 1986 +3 1941 1986 1987 +3 1942 1941 1987 +3 1943 1942 1987 +3 1943 1987 1988 +3 1943 1988 1989 +3 1944 1943 1989 +3 1945 1944 1989 +3 1945 1989 1990 +3 1945 1990 1991 +3 1946 1945 1991 +3 1947 1946 1991 +3 1947 1991 1992 +3 1947 1992 1993 +3 1948 1947 1993 +3 1949 1948 1993 +3 1949 1993 1994 +3 1949 1994 1995 +3 1950 1949 1995 +3 1951 1950 1995 +3 1951 1995 1996 +3 1951 1996 1997 +3 1952 1951 1997 +3 1953 1952 1997 +3 1953 1997 1998 +3 1953 1998 1999 +3 1954 1953 1999 +3 1955 1954 1999 +3 1955 1999 2000 +3 1955 2000 2001 +3 1956 1955 2001 +3 1957 1956 2001 +3 1957 2001 2002 +3 1957 2002 1912 +3 1958 1822 2003 +3 1959 1958 2003 +3 1959 2003 2004 +3 1959 2004 2005 +3 1960 1959 2005 +3 1961 1960 2005 +3 1961 2005 2006 +3 1961 2006 2007 +3 1962 1961 2007 +3 1963 1962 2007 +3 1963 2007 2008 +3 1963 2008 2009 +3 1964 1963 2009 +3 1965 1964 2009 +3 1965 2009 2010 +3 1965 2010 2011 +3 1966 1965 2011 +3 1967 1966 2011 +3 1967 2011 2012 +3 1967 2012 2013 +3 1968 1967 2013 +3 1969 1968 2013 +3 1969 2013 2014 +3 1969 2014 2015 +3 1970 1969 2015 +3 1971 1970 2015 +3 1971 2015 2016 +3 1971 2016 2017 +3 1972 1971 2017 +3 1973 1972 2017 +3 1973 2017 2018 +3 1973 2018 2019 +3 1974 1973 2019 +3 1975 1974 2019 +3 1975 2019 2020 +3 1975 2020 2021 +3 1976 1975 2021 +3 1977 1976 2021 +3 1977 2021 2022 +3 1977 2022 2023 +3 1978 1977 2023 +3 1979 1978 2023 +3 1979 2023 2024 +3 1979 2024 2025 +3 1980 1979 2025 +3 1981 1980 2025 +3 1981 2025 2026 +3 1981 2026 2027 +3 1982 1981 2027 +3 1983 1982 2027 +3 1983 2027 2028 +3 1983 2028 2029 +3 1984 1983 2029 +3 1985 1984 2029 +3 1985 2029 2030 +3 1985 2030 2031 +3 1986 1985 2031 +3 1987 1986 2031 +3 1987 2031 2032 +3 1987 2032 2033 +3 1988 1987 2033 +3 1989 1988 2033 +3 1989 2033 2034 +3 1989 2034 2035 +3 1990 1989 2035 +3 1991 1990 2035 +3 1991 2035 2036 +3 1991 2036 2037 +3 1992 1991 2037 +3 1993 1992 2037 +3 1993 2037 2038 +3 1993 2038 2039 +3 1994 1993 2039 +3 1995 1994 2039 +3 1995 2039 2040 +3 1995 2040 2041 +3 1996 1995 2041 +3 1997 1996 2041 +3 1997 2041 2042 +3 1997 2042 2043 +3 1998 1997 2043 +3 1999 1998 2043 +3 1999 2043 2044 +3 1999 2044 2045 +3 2000 1999 2045 +3 2001 2000 2045 +3 2001 2045 2046 +3 2001 2046 2047 +3 2002 2001 2047 +3 1912 2002 2047 +3 2003 1822 2048 +3 2003 2048 2049 +3 2004 2003 2049 +3 2005 2004 2049 +3 2005 2049 2050 +3 2005 2050 2051 +3 2006 2005 2051 +3 2007 2006 2051 +3 2007 2051 2052 +3 2007 2052 2053 +3 2008 2007 2053 +3 2009 2008 2053 +3 2009 2053 2054 +3 2009 2054 2055 +3 2010 2009 2055 +3 2011 2010 2055 +3 2011 2055 2056 +3 2011 2056 2057 +3 2012 2011 2057 +3 2013 2012 2057 +3 2013 2057 2058 +3 2013 2058 2059 +3 2014 2013 2059 +3 2015 2014 2059 +3 2015 2059 2060 +3 2015 2060 2061 +3 2016 2015 2061 +3 2017 2016 2061 +3 2017 2061 2062 +3 2017 2062 2063 +3 2018 2017 2063 +3 2019 2018 2063 +3 2019 2063 2064 +3 2019 2064 2065 +3 2020 2019 2065 +3 2021 2020 2065 +3 2021 2065 2066 +3 2021 2066 2067 +3 2022 2021 2067 +3 2023 2022 2067 +3 2023 2067 2068 +3 2023 2068 2069 +3 2024 2023 2069 +3 2025 2024 2069 +3 2025 2069 2070 +3 2025 2070 2071 +3 2026 2025 2071 +3 2027 2026 2071 +3 2027 2071 2072 +3 2027 2072 2073 +3 2028 2027 2073 +3 2029 2028 2073 +3 2029 2073 2074 +3 2029 2074 2075 +3 2030 2029 2075 +3 2031 2030 2075 +3 2031 2075 2076 +3 2031 2076 2077 +3 2032 2031 2077 +3 2033 2032 2077 +3 2033 2077 2078 +3 2033 2078 2079 +3 2034 2033 2079 +3 2035 2034 2079 +3 2035 2079 2080 +3 2035 2080 2081 +3 2036 2035 2081 +3 2037 2036 2081 +3 2037 2081 2082 +3 2037 2082 2083 +3 2038 2037 2083 +3 2039 2038 2083 +3 2039 2083 2084 +3 2039 2084 2085 +3 2040 2039 2085 +3 2041 2040 2085 +3 2041 2085 2086 +3 2041 2086 2087 +3 2042 2041 2087 +3 2043 2042 2087 +3 2043 2087 2088 +3 2043 2088 2089 +3 2044 2043 2089 +3 2045 2044 2089 +3 2045 2089 2090 +3 2045 2090 2091 +3 2046 2045 2091 +3 2047 2046 2091 +3 2047 2091 2092 +3 2047 2092 1912 +3 2048 1822 2093 +3 2049 2048 2093 +3 2049 2093 2094 +3 2049 2094 2095 +3 2050 2049 2095 +3 2051 2050 2095 +3 2051 2095 2096 +3 2051 2096 2097 +3 2052 2051 2097 +3 2053 2052 2097 +3 2053 2097 2098 +3 2053 2098 2099 +3 2054 2053 2099 +3 2055 2054 2099 +3 2055 2099 2100 +3 2055 2100 2101 +3 2056 2055 2101 +3 2057 2056 2101 +3 2057 2101 2102 +3 2057 2102 2103 +3 2058 2057 2103 +3 2059 2058 2103 +3 2059 2103 2104 +3 2059 2104 2105 +3 2060 2059 2105 +3 2061 2060 2105 +3 2061 2105 2106 +3 2061 2106 2107 +3 2062 2061 2107 +3 2063 2062 2107 +3 2063 2107 2108 +3 2063 2108 2109 +3 2064 2063 2109 +3 2065 2064 2109 +3 2065 2109 2110 +3 2065 2110 2111 +3 2066 2065 2111 +3 2067 2066 2111 +3 2067 2111 2112 +3 2067 2112 2113 +3 2068 2067 2113 +3 2069 2068 2113 +3 2069 2113 2114 +3 2069 2114 2115 +3 2070 2069 2115 +3 2071 2070 2115 +3 2071 2115 2116 +3 2071 2116 2117 +3 2072 2071 2117 +3 2073 2072 2117 +3 2073 2117 2118 +3 2073 2118 2119 +3 2074 2073 2119 +3 2075 2074 2119 +3 2075 2119 2120 +3 2075 2120 2121 +3 2076 2075 2121 +3 2077 2076 2121 +3 2077 2121 2122 +3 2077 2122 2123 +3 2078 2077 2123 +3 2079 2078 2123 +3 2079 2123 2124 +3 2079 2124 2125 +3 2080 2079 2125 +3 2081 2080 2125 +3 2081 2125 2126 +3 2081 2126 2127 +3 2082 2081 2127 +3 2083 2082 2127 +3 2083 2127 2128 +3 2083 2128 2129 +3 2084 2083 2129 +3 2085 2084 2129 +3 2085 2129 2130 +3 2085 2130 2131 +3 2086 2085 2131 +3 2087 2086 2131 +3 2087 2131 2132 +3 2087 2132 2133 +3 2088 2087 2133 +3 2089 2088 2133 +3 2089 2133 2134 +3 2089 2134 2135 +3 2090 2089 2135 +3 2091 2090 2135 +3 2091 2135 2136 +3 2091 2136 2137 +3 2092 2091 2137 +3 1912 2092 2137 +3 2093 1822 2138 +3 2093 2138 2139 +3 2094 2093 2139 +3 2095 2094 2139 +3 2095 2139 2140 +3 2095 2140 2141 +3 2096 2095 2141 +3 2097 2096 2141 +3 2097 2141 2142 +3 2097 2142 2143 +3 2098 2097 2143 +3 2099 2098 2143 +3 2099 2143 2144 +3 2099 2144 2145 +3 2100 2099 2145 +3 2101 2100 2145 +3 2101 2145 2146 +3 2101 2146 2147 +3 2102 2101 2147 +3 2103 2102 2147 +3 2103 2147 2148 +3 2103 2148 2149 +3 2104 2103 2149 +3 2105 2104 2149 +3 2105 2149 2150 +3 2105 2150 2151 +3 2106 2105 2151 +3 2107 2106 2151 +3 2107 2151 2152 +3 2107 2152 2153 +3 2108 2107 2153 +3 2109 2108 2153 +3 2109 2153 2154 +3 2109 2154 2155 +3 2110 2109 2155 +3 2111 2110 2155 +3 2111 2155 2156 +3 2111 2156 2157 +3 2112 2111 2157 +3 2113 2112 2157 +3 2113 2157 2158 +3 2113 2158 2159 +3 2114 2113 2159 +3 2115 2114 2159 +3 2115 2159 2160 +3 2115 2160 2161 +3 2116 2115 2161 +3 2117 2116 2161 +3 2117 2161 2162 +3 2117 2162 2163 +3 2118 2117 2163 +3 2119 2118 2163 +3 2119 2163 2164 +3 2119 2164 2165 +3 2120 2119 2165 +3 2121 2120 2165 +3 2121 2165 2166 +3 2121 2166 2167 +3 2122 2121 2167 +3 2123 2122 2167 +3 2123 2167 2168 +3 2123 2168 2169 +3 2124 2123 2169 +3 2125 2124 2169 +3 2125 2169 2170 +3 2125 2170 2171 +3 2126 2125 2171 +3 2127 2126 2171 +3 2127 2171 2172 +3 2127 2172 2173 +3 2128 2127 2173 +3 2129 2128 2173 +3 2129 2173 2174 +3 2129 2174 2175 +3 2130 2129 2175 +3 2131 2130 2175 +3 2131 2175 2176 +3 2131 2176 2177 +3 2132 2131 2177 +3 2133 2132 2177 +3 2133 2177 2178 +3 2133 2178 2179 +3 2134 2133 2179 +3 2135 2134 2179 +3 2135 2179 2180 +3 2135 2180 2181 +3 2136 2135 2181 +3 2137 2136 2181 +3 2137 2181 2182 +3 2137 2182 1912 +3 2138 1822 1821 +3 2139 2138 1821 +3 2139 1821 1825 +3 2139 1825 1826 +3 2140 2139 1826 +3 2141 2140 1826 +3 2141 1826 1829 +3 2141 1829 1830 +3 2142 2141 1830 +3 2143 2142 1830 +3 2143 1830 1833 +3 2143 1833 1834 +3 2144 2143 1834 +3 2145 2144 1834 +3 2145 1834 1837 +3 2145 1837 1838 +3 2146 2145 1838 +3 2147 2146 1838 +3 2147 1838 1841 +3 2147 1841 1842 +3 2148 2147 1842 +3 2149 2148 1842 +3 2149 1842 1845 +3 2149 1845 1846 +3 2150 2149 1846 +3 2151 2150 1846 +3 2151 1846 1849 +3 2151 1849 1850 +3 2152 2151 1850 +3 2153 2152 1850 +3 2153 1850 1853 +3 2153 1853 1854 +3 2154 2153 1854 +3 2155 2154 1854 +3 2155 1854 1857 +3 2155 1857 1858 +3 2156 2155 1858 +3 2157 2156 1858 +3 2157 1858 1861 +3 2157 1861 1862 +3 2158 2157 1862 +3 2159 2158 1862 +3 2159 1862 1865 +3 2159 1865 1866 +3 2160 2159 1866 +3 2161 2160 1866 +3 2161 1866 1869 +3 2161 1869 1870 +3 2162 2161 1870 +3 2163 2162 1870 +3 2163 1870 1873 +3 2163 1873 1874 +3 2164 2163 1874 +3 2165 2164 1874 +3 2165 1874 1877 +3 2165 1877 1878 +3 2166 2165 1878 +3 2167 2166 1878 +3 2167 1878 1881 +3 2167 1881 1882 +3 2168 2167 1882 +3 2169 2168 1882 +3 2169 1882 1885 +3 2169 1885 1886 +3 2170 2169 1886 +3 2171 2170 1886 +3 2171 1886 1889 +3 2171 1889 1890 +3 2172 2171 1890 +3 2173 2172 1890 +3 2173 1890 1893 +3 2173 1893 1894 +3 2174 2173 1894 +3 2175 2174 1894 +3 2175 1894 1897 +3 2175 1897 1898 +3 2176 2175 1898 +3 2177 2176 1898 +3 2177 1898 1901 +3 2177 1901 1902 +3 2178 2177 1902 +3 2179 2178 1902 +3 2179 1902 1905 +3 2179 1905 1906 +3 2180 2179 1906 +3 2181 2180 1906 +3 2181 1906 1909 +3 2181 1909 1910 +3 2182 2181 1910 +3 1912 2182 1910 +3 2183 2184 2185 +3 2183 2185 2186 +3 2187 2183 2186 +3 2188 2187 2186 +3 2188 2186 2189 +3 2188 2189 2190 +3 2191 2188 2190 +3 2192 2191 2190 +3 2192 2190 2193 +3 2192 2193 2194 +3 2195 2192 2194 +3 2196 2195 2194 +3 2196 2194 2197 +3 2196 2197 2198 +3 2199 2196 2198 +3 2200 2199 2198 +3 2200 2198 2201 +3 2200 2201 2202 +3 2203 2200 2202 +3 2204 2203 2202 +3 2204 2202 2205 +3 2204 2205 2206 +3 2207 2204 2206 +3 2208 2207 2206 +3 2208 2206 2209 +3 2208 2209 2210 +3 2211 2208 2210 +3 2212 2211 2210 +3 2212 2210 2213 +3 2212 2213 2214 +3 2215 2212 2214 +3 2216 2215 2214 +3 2216 2214 2217 +3 2216 2217 2218 +3 2219 2216 2218 +3 2220 2219 2218 +3 2220 2218 2221 +3 2220 2221 2222 +3 2223 2220 2222 +3 2224 2223 2222 +3 2224 2222 2225 +3 2224 2225 2226 +3 2227 2224 2226 +3 2228 2227 2226 +3 2228 2226 2229 +3 2228 2229 2230 +3 2231 2228 2230 +3 2232 2231 2230 +3 2232 2230 2233 +3 2232 2233 2234 +3 2235 2232 2234 +3 2236 2235 2234 +3 2236 2234 2237 +3 2236 2237 2238 +3 2239 2236 2238 +3 2240 2239 2238 +3 2240 2238 2241 +3 2240 2241 2242 +3 2243 2240 2242 +3 2244 2243 2242 +3 2244 2242 2245 +3 2244 2245 2246 +3 2247 2244 2246 +3 2248 2247 2246 +3 2248 2246 2249 +3 2248 2249 2250 +3 2251 2248 2250 +3 2252 2251 2250 +3 2252 2250 2253 +3 2252 2253 2254 +3 2255 2252 2254 +3 2256 2255 2254 +3 2256 2254 2257 +3 2256 2257 2258 +3 2259 2256 2258 +3 2260 2259 2258 +3 2260 2258 2261 +3 2260 2261 2262 +3 2263 2260 2262 +3 2264 2263 2262 +3 2264 2262 2265 +3 2264 2265 2266 +3 2267 2264 2266 +3 2268 2267 2266 +3 2268 2266 2269 +3 2268 2269 2270 +3 2271 2268 2270 +3 1910 2271 2270 +3 1910 2270 2272 +3 1910 2272 1912 +3 2185 2184 2273 +3 2186 2185 2273 +3 2186 2273 2274 +3 2186 2274 2275 +3 2189 2186 2275 +3 2190 2189 2275 +3 2190 2275 2276 +3 2190 2276 2277 +3 2193 2190 2277 +3 2194 2193 2277 +3 2194 2277 2278 +3 2194 2278 2279 +3 2197 2194 2279 +3 2198 2197 2279 +3 2198 2279 2280 +3 2198 2280 2281 +3 2201 2198 2281 +3 2202 2201 2281 +3 2202 2281 2282 +3 2202 2282 2283 +3 2205 2202 2283 +3 2206 2205 2283 +3 2206 2283 2284 +3 2206 2284 2285 +3 2209 2206 2285 +3 2210 2209 2285 +3 2210 2285 2286 +3 2210 2286 2287 +3 2213 2210 2287 +3 2214 2213 2287 +3 2214 2287 2288 +3 2214 2288 2289 +3 2217 2214 2289 +3 2218 2217 2289 +3 2218 2289 2290 +3 2218 2290 2291 +3 2221 2218 2291 +3 2222 2221 2291 +3 2222 2291 2292 +3 2222 2292 2293 +3 2225 2222 2293 +3 2226 2225 2293 +3 2226 2293 2294 +3 2226 2294 2295 +3 2229 2226 2295 +3 2230 2229 2295 +3 2230 2295 2296 +3 2230 2296 2297 +3 2233 2230 2297 +3 2234 2233 2297 +3 2234 2297 2298 +3 2234 2298 2299 +3 2237 2234 2299 +3 2238 2237 2299 +3 2238 2299 2300 +3 2238 2300 2301 +3 2241 2238 2301 +3 2242 2241 2301 +3 2242 2301 2302 +3 2242 2302 2303 +3 2245 2242 2303 +3 2246 2245 2303 +3 2246 2303 2304 +3 2246 2304 2305 +3 2249 2246 2305 +3 2250 2249 2305 +3 2250 2305 2306 +3 2250 2306 2307 +3 2253 2250 2307 +3 2254 2253 2307 +3 2254 2307 2308 +3 2254 2308 2309 +3 2257 2254 2309 +3 2258 2257 2309 +3 2258 2309 2310 +3 2258 2310 2311 +3 2261 2258 2311 +3 2262 2261 2311 +3 2262 2311 2312 +3 2262 2312 2313 +3 2265 2262 2313 +3 2266 2265 2313 +3 2266 2313 2314 +3 2266 2314 2315 +3 2269 2266 2315 +3 2270 2269 2315 +3 2270 2315 2316 +3 2270 2316 2317 +3 2272 2270 2317 +3 1912 2272 2317 +3 2273 2184 2318 +3 2273 2318 2319 +3 2274 2273 2319 +3 2275 2274 2319 +3 2275 2319 2320 +3 2275 2320 2321 +3 2276 2275 2321 +3 2277 2276 2321 +3 2277 2321 2322 +3 2277 2322 2323 +3 2278 2277 2323 +3 2279 2278 2323 +3 2279 2323 2324 +3 2279 2324 2325 +3 2280 2279 2325 +3 2281 2280 2325 +3 2281 2325 2326 +3 2281 2326 2327 +3 2282 2281 2327 +3 2283 2282 2327 +3 2283 2327 2328 +3 2283 2328 2329 +3 2284 2283 2329 +3 2285 2284 2329 +3 2285 2329 2330 +3 2285 2330 2331 +3 2286 2285 2331 +3 2287 2286 2331 +3 2287 2331 2332 +3 2287 2332 2333 +3 2288 2287 2333 +3 2289 2288 2333 +3 2289 2333 2334 +3 2289 2334 2335 +3 2290 2289 2335 +3 2291 2290 2335 +3 2291 2335 2336 +3 2291 2336 2337 +3 2292 2291 2337 +3 2293 2292 2337 +3 2293 2337 2338 +3 2293 2338 2339 +3 2294 2293 2339 +3 2295 2294 2339 +3 2295 2339 2340 +3 2295 2340 2341 +3 2296 2295 2341 +3 2297 2296 2341 +3 2297 2341 2342 +3 2297 2342 2343 +3 2298 2297 2343 +3 2299 2298 2343 +3 2299 2343 2344 +3 2299 2344 2345 +3 2300 2299 2345 +3 2301 2300 2345 +3 2301 2345 2346 +3 2301 2346 2347 +3 2302 2301 2347 +3 2303 2302 2347 +3 2303 2347 2348 +3 2303 2348 2349 +3 2304 2303 2349 +3 2305 2304 2349 +3 2305 2349 2350 +3 2305 2350 2351 +3 2306 2305 2351 +3 2307 2306 2351 +3 2307 2351 2352 +3 2307 2352 2353 +3 2308 2307 2353 +3 2309 2308 2353 +3 2309 2353 2354 +3 2309 2354 2355 +3 2310 2309 2355 +3 2311 2310 2355 +3 2311 2355 2356 +3 2311 2356 2357 +3 2312 2311 2357 +3 2313 2312 2357 +3 2313 2357 2358 +3 2313 2358 2359 +3 2314 2313 2359 +3 2315 2314 2359 +3 2315 2359 2360 +3 2315 2360 2361 +3 2316 2315 2361 +3 2317 2316 2361 +3 2317 2361 2362 +3 2317 2362 1912 +3 2318 2184 2363 +3 2319 2318 2363 +3 2319 2363 2364 +3 2319 2364 2365 +3 2320 2319 2365 +3 2321 2320 2365 +3 2321 2365 2366 +3 2321 2366 2367 +3 2322 2321 2367 +3 2323 2322 2367 +3 2323 2367 2368 +3 2323 2368 2369 +3 2324 2323 2369 +3 2325 2324 2369 +3 2325 2369 2370 +3 2325 2370 2371 +3 2326 2325 2371 +3 2327 2326 2371 +3 2327 2371 2372 +3 2327 2372 2373 +3 2328 2327 2373 +3 2329 2328 2373 +3 2329 2373 2374 +3 2329 2374 2375 +3 2330 2329 2375 +3 2331 2330 2375 +3 2331 2375 2376 +3 2331 2376 2377 +3 2332 2331 2377 +3 2333 2332 2377 +3 2333 2377 2378 +3 2333 2378 2379 +3 2334 2333 2379 +3 2335 2334 2379 +3 2335 2379 2380 +3 2335 2380 2381 +3 2336 2335 2381 +3 2337 2336 2381 +3 2337 2381 2382 +3 2337 2382 2383 +3 2338 2337 2383 +3 2339 2338 2383 +3 2339 2383 2384 +3 2339 2384 2385 +3 2340 2339 2385 +3 2341 2340 2385 +3 2341 2385 2386 +3 2341 2386 2387 +3 2342 2341 2387 +3 2343 2342 2387 +3 2343 2387 2388 +3 2343 2388 2389 +3 2344 2343 2389 +3 2345 2344 2389 +3 2345 2389 2390 +3 2345 2390 2391 +3 2346 2345 2391 +3 2347 2346 2391 +3 2347 2391 2392 +3 2347 2392 2393 +3 2348 2347 2393 +3 2349 2348 2393 +3 2349 2393 2394 +3 2349 2394 2395 +3 2350 2349 2395 +3 2351 2350 2395 +3 2351 2395 2396 +3 2351 2396 2397 +3 2352 2351 2397 +3 2353 2352 2397 +3 2353 2397 2398 +3 2353 2398 2399 +3 2354 2353 2399 +3 2355 2354 2399 +3 2355 2399 2400 +3 2355 2400 2401 +3 2356 2355 2401 +3 2357 2356 2401 +3 2357 2401 2402 +3 2357 2402 2403 +3 2358 2357 2403 +3 2359 2358 2403 +3 2359 2403 2404 +3 2359 2404 2405 +3 2360 2359 2405 +3 2361 2360 2405 +3 2361 2405 2406 +3 2361 2406 2047 +3 2362 2361 2047 +3 1912 2362 2047 +3 2363 2184 2407 +3 2363 2407 2408 +3 2364 2363 2408 +3 2365 2364 2408 +3 2365 2408 2409 +3 2365 2409 2410 +3 2366 2365 2410 +3 2367 2366 2410 +3 2367 2410 2411 +3 2367 2411 2412 +3 2368 2367 2412 +3 2369 2368 2412 +3 2369 2412 2413 +3 2369 2413 2414 +3 2370 2369 2414 +3 2371 2370 2414 +3 2371 2414 2415 +3 2371 2415 2416 +3 2372 2371 2416 +3 2373 2372 2416 +3 2373 2416 2417 +3 2373 2417 2418 +3 2374 2373 2418 +3 2375 2374 2418 +3 2375 2418 2419 +3 2375 2419 2420 +3 2376 2375 2420 +3 2377 2376 2420 +3 2377 2420 2421 +3 2377 2421 2422 +3 2378 2377 2422 +3 2379 2378 2422 +3 2379 2422 2423 +3 2379 2423 2424 +3 2380 2379 2424 +3 2381 2380 2424 +3 2381 2424 2425 +3 2381 2425 2426 +3 2382 2381 2426 +3 2383 2382 2426 +3 2383 2426 2427 +3 2383 2427 2428 +3 2384 2383 2428 +3 2385 2384 2428 +3 2385 2428 2429 +3 2385 2429 2430 +3 2386 2385 2430 +3 2387 2386 2430 +3 2387 2430 2431 +3 2387 2431 2432 +3 2388 2387 2432 +3 2389 2388 2432 +3 2389 2432 2433 +3 2389 2433 2434 +3 2390 2389 2434 +3 2391 2390 2434 +3 2391 2434 2435 +3 2391 2435 2436 +3 2392 2391 2436 +3 2393 2392 2436 +3 2393 2436 2437 +3 2393 2437 2438 +3 2394 2393 2438 +3 2395 2394 2438 +3 2395 2438 2439 +3 2395 2439 2440 +3 2396 2395 2440 +3 2397 2396 2440 +3 2397 2440 2441 +3 2397 2441 2442 +3 2398 2397 2442 +3 2399 2398 2442 +3 2399 2442 2443 +3 2399 2443 2444 +3 2400 2399 2444 +3 2401 2400 2444 +3 2401 2444 2445 +3 2401 2445 2446 +3 2402 2401 2446 +3 2403 2402 2446 +3 2403 2446 2447 +3 2403 2447 2448 +3 2404 2403 2448 +3 2405 2404 2448 +3 2405 2448 2449 +3 2405 2449 2450 +3 2406 2405 2450 +3 2047 2406 2450 +3 2047 2450 2451 +3 2047 2451 1912 +3 2407 2184 2452 +3 2408 2407 2452 +3 2408 2452 2453 +3 2408 2453 2454 +3 2409 2408 2454 +3 2410 2409 2454 +3 2410 2454 2455 +3 2410 2455 2456 +3 2411 2410 2456 +3 2412 2411 2456 +3 2412 2456 2457 +3 2412 2457 2458 +3 2413 2412 2458 +3 2414 2413 2458 +3 2414 2458 2459 +3 2414 2459 2460 +3 2415 2414 2460 +3 2416 2415 2460 +3 2416 2460 2461 +3 2416 2461 2462 +3 2417 2416 2462 +3 2418 2417 2462 +3 2418 2462 2463 +3 2418 2463 2464 +3 2419 2418 2464 +3 2420 2419 2464 +3 2420 2464 2465 +3 2420 2465 2466 +3 2421 2420 2466 +3 2422 2421 2466 +3 2422 2466 2467 +3 2422 2467 2468 +3 2423 2422 2468 +3 2424 2423 2468 +3 2424 2468 2469 +3 2424 2469 2470 +3 2425 2424 2470 +3 2426 2425 2470 +3 2426 2470 2471 +3 2426 2471 2472 +3 2427 2426 2472 +3 2428 2427 2472 +3 2428 2472 2473 +3 2428 2473 2474 +3 2429 2428 2474 +3 2430 2429 2474 +3 2430 2474 2475 +3 2430 2475 2476 +3 2431 2430 2476 +3 2432 2431 2476 +3 2432 2476 2477 +3 2432 2477 2478 +3 2433 2432 2478 +3 2434 2433 2478 +3 2434 2478 2479 +3 2434 2479 2480 +3 2435 2434 2480 +3 2436 2435 2480 +3 2436 2480 2481 +3 2436 2481 2482 +3 2437 2436 2482 +3 2438 2437 2482 +3 2438 2482 2483 +3 2438 2483 2484 +3 2439 2438 2484 +3 2440 2439 2484 +3 2440 2484 2485 +3 2440 2485 2486 +3 2441 2440 2486 +3 2442 2441 2486 +3 2442 2486 2487 +3 2442 2487 2488 +3 2443 2442 2488 +3 2444 2443 2488 +3 2444 2488 2489 +3 2444 2489 2490 +3 2445 2444 2490 +3 2446 2445 2490 +3 2446 2490 2491 +3 2446 2491 2492 +3 2447 2446 2492 +3 2448 2447 2492 +3 2448 2492 2493 +3 2448 2493 2494 +3 2449 2448 2494 +3 2450 2449 2494 +3 2450 2494 2495 +3 2450 2495 2496 +3 2451 2450 2496 +3 1912 2451 2496 +3 2452 2184 2497 +3 2452 2497 2498 +3 2453 2452 2498 +3 2454 2453 2498 +3 2454 2498 2499 +3 2454 2499 2500 +3 2455 2454 2500 +3 2456 2455 2500 +3 2456 2500 2501 +3 2456 2501 2502 +3 2457 2456 2502 +3 2458 2457 2502 +3 2458 2502 2503 +3 2458 2503 2504 +3 2459 2458 2504 +3 2460 2459 2504 +3 2460 2504 2505 +3 2460 2505 2506 +3 2461 2460 2506 +3 2462 2461 2506 +3 2462 2506 2507 +3 2462 2507 2508 +3 2463 2462 2508 +3 2464 2463 2508 +3 2464 2508 2509 +3 2464 2509 2510 +3 2465 2464 2510 +3 2466 2465 2510 +3 2466 2510 2511 +3 2466 2511 2512 +3 2467 2466 2512 +3 2468 2467 2512 +3 2468 2512 2513 +3 2468 2513 2514 +3 2469 2468 2514 +3 2470 2469 2514 +3 2470 2514 2515 +3 2470 2515 2516 +3 2471 2470 2516 +3 2472 2471 2516 +3 2472 2516 2517 +3 2472 2517 2518 +3 2473 2472 2518 +3 2474 2473 2518 +3 2474 2518 2519 +3 2474 2519 2520 +3 2475 2474 2520 +3 2476 2475 2520 +3 2476 2520 2521 +3 2476 2521 2522 +3 2477 2476 2522 +3 2478 2477 2522 +3 2478 2522 2523 +3 2478 2523 2524 +3 2479 2478 2524 +3 2480 2479 2524 +3 2480 2524 2525 +3 2480 2525 2526 +3 2481 2480 2526 +3 2482 2481 2526 +3 2482 2526 2527 +3 2482 2527 2528 +3 2483 2482 2528 +3 2484 2483 2528 +3 2484 2528 2529 +3 2484 2529 2530 +3 2485 2484 2530 +3 2486 2485 2530 +3 2486 2530 2531 +3 2486 2531 2532 +3 2487 2486 2532 +3 2488 2487 2532 +3 2488 2532 2533 +3 2488 2533 2534 +3 2489 2488 2534 +3 2490 2489 2534 +3 2490 2534 2535 +3 2490 2535 2536 +3 2491 2490 2536 +3 2492 2491 2536 +3 2492 2536 2537 +3 2492 2537 2538 +3 2493 2492 2538 +3 2494 2493 2538 +3 2494 2538 2539 +3 2494 2539 2540 +3 2495 2494 2540 +3 2496 2495 2540 +3 2496 2540 2541 +3 2496 2541 1912 +3 2497 2184 2183 +3 2498 2497 2183 +3 2498 2183 2187 +3 2498 2187 2188 +3 2499 2498 2188 +3 2500 2499 2188 +3 2500 2188 2191 +3 2500 2191 2192 +3 2501 2500 2192 +3 2502 2501 2192 +3 2502 2192 2195 +3 2502 2195 2196 +3 2503 2502 2196 +3 2504 2503 2196 +3 2504 2196 2199 +3 2504 2199 2200 +3 2505 2504 2200 +3 2506 2505 2200 +3 2506 2200 2203 +3 2506 2203 2204 +3 2507 2506 2204 +3 2508 2507 2204 +3 2508 2204 2207 +3 2508 2207 2208 +3 2509 2508 2208 +3 2510 2509 2208 +3 2510 2208 2211 +3 2510 2211 2212 +3 2511 2510 2212 +3 2512 2511 2212 +3 2512 2212 2215 +3 2512 2215 2216 +3 2513 2512 2216 +3 2514 2513 2216 +3 2514 2216 2219 +3 2514 2219 2220 +3 2515 2514 2220 +3 2516 2515 2220 +3 2516 2220 2223 +3 2516 2223 2224 +3 2517 2516 2224 +3 2518 2517 2224 +3 2518 2224 2227 +3 2518 2227 2228 +3 2519 2518 2228 +3 2520 2519 2228 +3 2520 2228 2231 +3 2520 2231 2232 +3 2521 2520 2232 +3 2522 2521 2232 +3 2522 2232 2235 +3 2522 2235 2236 +3 2523 2522 2236 +3 2524 2523 2236 +3 2524 2236 2239 +3 2524 2239 2240 +3 2525 2524 2240 +3 2526 2525 2240 +3 2526 2240 2243 +3 2526 2243 2244 +3 2527 2526 2244 +3 2528 2527 2244 +3 2528 2244 2247 +3 2528 2247 2248 +3 2529 2528 2248 +3 2530 2529 2248 +3 2530 2248 2251 +3 2530 2251 2252 +3 2531 2530 2252 +3 2532 2531 2252 +3 2532 2252 2255 +3 2532 2255 2256 +3 2533 2532 2256 +3 2534 2533 2256 +3 2534 2256 2259 +3 2534 2259 2260 +3 2535 2534 2260 +3 2536 2535 2260 +3 2536 2260 2263 +3 2536 2263 2264 +3 2537 2536 2264 +3 2538 2537 2264 +3 2538 2264 2267 +3 2538 2267 2268 +3 2539 2538 2268 +3 2540 2539 2268 +3 2540 2268 2271 +3 2540 2271 1910 +3 2541 2540 1910 +3 1912 2541 1910 +3 2542 2543 2544 +3 2542 2544 2545 +3 2546 2542 2545 +3 2547 2546 2545 +3 2547 2545 2548 +3 2547 2548 2549 +3 2550 2547 2549 +3 2551 2550 2549 +3 2551 2549 2552 +3 2551 2552 2553 +3 2554 2551 2553 +3 2555 2554 2553 +3 2555 2553 2556 +3 2555 2556 2557 +3 2558 2555 2557 +3 2559 2558 2557 +3 2559 2557 2560 +3 2559 2560 2561 +3 2562 2559 2561 +3 2563 2562 2561 +3 2563 2561 2564 +3 2563 2564 2565 +3 2566 2563 2565 +3 2567 2566 2565 +3 2567 2565 2568 +3 2567 2568 2569 +3 2570 2567 2569 +3 2571 2570 2569 +3 2571 2569 2572 +3 2571 2572 2573 +3 2574 2571 2573 +3 2575 2574 2573 +3 2575 2573 2576 +3 2575 2576 2577 +3 2578 2575 2577 +3 2579 2578 2577 +3 2579 2577 2580 +3 2579 2580 2581 +3 2582 2579 2581 +3 2583 2582 2581 +3 2583 2581 2584 +3 2583 2584 2585 +3 2586 2583 2585 +3 2587 2586 2585 +3 2587 2585 2588 +3 2587 2588 2589 +3 2590 2587 2589 +3 2591 2590 2589 +3 2591 2589 2592 +3 2591 2592 2593 +3 2594 2591 2593 +3 2595 2594 2593 +3 2595 2593 2596 +3 2595 2596 2597 +3 2598 2595 2597 +3 2599 2598 2597 +3 2599 2597 2600 +3 2599 2600 2601 +3 2602 2599 2601 +3 2603 2602 2601 +3 2603 2601 2604 +3 2603 2604 2605 +3 2606 2603 2605 +3 2607 2606 2605 +3 2607 2605 2608 +3 2607 2608 2609 +3 2610 2607 2609 +3 2611 2610 2609 +3 2611 2609 2612 +3 2611 2612 2613 +3 2614 2611 2613 +3 2615 2614 2613 +3 2615 2613 2616 +3 2615 2616 2617 +3 2618 2615 2617 +3 2619 2618 2617 +3 2619 2617 2620 +3 2619 2620 2621 +3 2622 2619 2621 +3 2623 2622 2621 +3 2623 2621 2624 +3 2623 2624 2625 +3 2626 2623 2625 +3 2627 2626 2625 +3 2627 2625 2628 +3 2627 2628 2629 +3 2630 2627 2629 +3 2631 2630 2629 +3 2631 2629 2632 +3 2631 2632 2633 +3 2544 2543 2634 +3 2545 2544 2634 +3 2545 2634 2635 +3 2545 2635 2636 +3 2548 2545 2636 +3 2549 2548 2636 +3 2549 2636 2637 +3 2549 2637 2638 +3 2552 2549 2638 +3 2553 2552 2638 +3 2553 2638 2639 +3 2553 2639 2640 +3 2556 2553 2640 +3 2557 2556 2640 +3 2557 2640 2641 +3 2557 2641 2642 +3 2560 2557 2642 +3 2561 2560 2642 +3 2561 2642 2643 +3 2561 2643 2644 +3 2564 2561 2644 +3 2565 2564 2644 +3 2565 2644 2645 +3 2565 2645 2646 +3 2568 2565 2646 +3 2569 2568 2646 +3 2569 2646 2647 +3 2569 2647 2648 +3 2572 2569 2648 +3 2573 2572 2648 +3 2573 2648 2649 +3 2573 2649 2650 +3 2576 2573 2650 +3 2577 2576 2650 +3 2577 2650 2651 +3 2577 2651 2652 +3 2580 2577 2652 +3 2581 2580 2652 +3 2581 2652 2653 +3 2581 2653 2654 +3 2584 2581 2654 +3 2585 2584 2654 +3 2585 2654 2655 +3 2585 2655 2656 +3 2588 2585 2656 +3 2589 2588 2656 +3 2589 2656 2657 +3 2589 2657 2658 +3 2592 2589 2658 +3 2593 2592 2658 +3 2593 2658 2659 +3 2593 2659 2660 +3 2596 2593 2660 +3 2597 2596 2660 +3 2597 2660 2661 +3 2597 2661 2662 +3 2600 2597 2662 +3 2601 2600 2662 +3 2601 2662 2663 +3 2601 2663 2664 +3 2604 2601 2664 +3 2605 2604 2664 +3 2605 2664 2665 +3 2605 2665 2666 +3 2608 2605 2666 +3 2609 2608 2666 +3 2609 2666 2667 +3 2609 2667 2668 +3 2612 2609 2668 +3 2613 2612 2668 +3 2613 2668 2669 +3 2613 2669 2670 +3 2616 2613 2670 +3 2617 2616 2670 +3 2617 2670 2671 +3 2617 2671 2672 +3 2620 2617 2672 +3 2621 2620 2672 +3 2621 2672 2673 +3 2621 2673 2674 +3 2624 2621 2674 +3 2625 2624 2674 +3 2625 2674 2675 +3 2625 2675 2676 +3 2628 2625 2676 +3 2629 2628 2676 +3 2629 2676 2677 +3 2629 2677 2678 +3 2632 2629 2678 +3 2633 2632 2678 +3 2634 2543 2679 +3 2634 2679 2680 +3 2635 2634 2680 +3 2636 2635 2680 +3 2636 2680 2681 +3 2636 2681 2682 +3 2637 2636 2682 +3 2638 2637 2682 +3 2638 2682 2683 +3 2638 2683 2684 +3 2639 2638 2684 +3 2640 2639 2684 +3 2640 2684 2685 +3 2640 2685 2686 +3 2641 2640 2686 +3 2642 2641 2686 +3 2642 2686 2687 +3 2642 2687 2688 +3 2643 2642 2688 +3 2644 2643 2688 +3 2644 2688 2689 +3 2644 2689 2690 +3 2645 2644 2690 +3 2646 2645 2690 +3 2646 2690 2691 +3 2646 2691 2692 +3 2647 2646 2692 +3 2648 2647 2692 +3 2648 2692 2693 +3 2648 2693 2694 +3 2649 2648 2694 +3 2650 2649 2694 +3 2650 2694 2695 +3 2650 2695 2696 +3 2651 2650 2696 +3 2652 2651 2696 +3 2652 2696 2697 +3 2652 2697 2698 +3 2653 2652 2698 +3 2654 2653 2698 +3 2654 2698 2699 +3 2654 2699 2700 +3 2655 2654 2700 +3 2656 2655 2700 +3 2656 2700 2701 +3 2656 2701 2702 +3 2657 2656 2702 +3 2658 2657 2702 +3 2658 2702 2703 +3 2658 2703 2704 +3 2659 2658 2704 +3 2660 2659 2704 +3 2660 2704 2705 +3 2660 2705 2706 +3 2661 2660 2706 +3 2662 2661 2706 +3 2662 2706 2707 +3 2662 2707 2708 +3 2663 2662 2708 +3 2664 2663 2708 +3 2664 2708 2709 +3 2664 2709 2710 +3 2665 2664 2710 +3 2666 2665 2710 +3 2666 2710 2711 +3 2666 2711 2712 +3 2667 2666 2712 +3 2668 2667 2712 +3 2668 2712 2713 +3 2668 2713 2714 +3 2669 2668 2714 +3 2670 2669 2714 +3 2670 2714 2715 +3 2670 2715 2716 +3 2671 2670 2716 +3 2672 2671 2716 +3 2672 2716 2717 +3 2672 2717 2718 +3 2673 2672 2718 +3 2674 2673 2718 +3 2674 2718 2719 +3 2674 2719 2720 +3 2675 2674 2720 +3 2676 2675 2720 +3 2676 2720 2721 +3 2676 2721 2722 +3 2677 2676 2722 +3 2678 2677 2722 +3 2678 2722 2723 +3 2678 2723 2633 +3 2679 2543 2724 +3 2680 2679 2724 +3 2680 2724 2725 +3 2680 2725 2726 +3 2681 2680 2726 +3 2682 2681 2726 +3 2682 2726 2727 +3 2682 2727 2728 +3 2683 2682 2728 +3 2684 2683 2728 +3 2684 2728 2729 +3 2684 2729 2730 +3 2685 2684 2730 +3 2686 2685 2730 +3 2686 2730 2731 +3 2686 2731 2732 +3 2687 2686 2732 +3 2688 2687 2732 +3 2688 2732 2733 +3 2688 2733 2734 +3 2689 2688 2734 +3 2690 2689 2734 +3 2690 2734 2735 +3 2690 2735 2736 +3 2691 2690 2736 +3 2692 2691 2736 +3 2692 2736 2737 +3 2692 2737 2738 +3 2693 2692 2738 +3 2694 2693 2738 +3 2694 2738 2739 +3 2694 2739 2740 +3 2695 2694 2740 +3 2696 2695 2740 +3 2696 2740 2741 +3 2696 2741 2742 +3 2697 2696 2742 +3 2698 2697 2742 +3 2698 2742 2743 +3 2698 2743 2744 +3 2699 2698 2744 +3 2700 2699 2744 +3 2700 2744 2745 +3 2700 2745 2746 +3 2701 2700 2746 +3 2702 2701 2746 +3 2702 2746 2747 +3 2702 2747 2748 +3 2703 2702 2748 +3 2704 2703 2748 +3 2704 2748 2749 +3 2704 2749 2750 +3 2705 2704 2750 +3 2706 2705 2750 +3 2706 2750 2751 +3 2706 2751 2752 +3 2707 2706 2752 +3 2708 2707 2752 +3 2708 2752 2753 +3 2708 2753 2754 +3 2709 2708 2754 +3 2710 2709 2754 +3 2710 2754 2755 +3 2710 2755 2756 +3 2711 2710 2756 +3 2712 2711 2756 +3 2712 2756 2757 +3 2712 2757 2758 +3 2713 2712 2758 +3 2714 2713 2758 +3 2714 2758 2759 +3 2714 2759 2760 +3 2715 2714 2760 +3 2716 2715 2760 +3 2716 2760 2761 +3 2716 2761 2762 +3 2717 2716 2762 +3 2718 2717 2762 +3 2718 2762 2763 +3 2718 2763 2764 +3 2719 2718 2764 +3 2720 2719 2764 +3 2720 2764 2765 +3 2720 2765 2766 +3 2721 2720 2766 +3 2722 2721 2766 +3 2722 2766 2767 +3 2722 2767 2768 +3 2723 2722 2768 +3 2633 2723 2768 +3 2724 2543 2769 +3 2724 2769 2770 +3 2725 2724 2770 +3 2726 2725 2770 +3 2726 2770 2771 +3 2726 2771 2772 +3 2727 2726 2772 +3 2728 2727 2772 +3 2728 2772 2773 +3 2728 2773 2774 +3 2729 2728 2774 +3 2730 2729 2774 +3 2730 2774 2775 +3 2730 2775 2776 +3 2731 2730 2776 +3 2732 2731 2776 +3 2732 2776 2777 +3 2732 2777 2778 +3 2733 2732 2778 +3 2734 2733 2778 +3 2734 2778 2779 +3 2734 2779 2780 +3 2735 2734 2780 +3 2736 2735 2780 +3 2736 2780 2781 +3 2736 2781 2782 +3 2737 2736 2782 +3 2738 2737 2782 +3 2738 2782 2783 +3 2738 2783 2784 +3 2739 2738 2784 +3 2740 2739 2784 +3 2740 2784 2785 +3 2740 2785 2786 +3 2741 2740 2786 +3 2742 2741 2786 +3 2742 2786 2787 +3 2742 2787 2788 +3 2743 2742 2788 +3 2744 2743 2788 +3 2744 2788 2789 +3 2744 2789 2790 +3 2745 2744 2790 +3 2746 2745 2790 +3 2746 2790 2791 +3 2746 2791 2792 +3 2747 2746 2792 +3 2748 2747 2792 +3 2748 2792 2793 +3 2748 2793 2794 +3 2749 2748 2794 +3 2750 2749 2794 +3 2750 2794 2795 +3 2750 2795 2796 +3 2751 2750 2796 +3 2752 2751 2796 +3 2752 2796 2797 +3 2752 2797 2798 +3 2753 2752 2798 +3 2754 2753 2798 +3 2754 2798 2799 +3 2754 2799 2800 +3 2755 2754 2800 +3 2756 2755 2800 +3 2756 2800 2801 +3 2756 2801 2802 +3 2757 2756 2802 +3 2758 2757 2802 +3 2758 2802 2803 +3 2758 2803 2804 +3 2759 2758 2804 +3 2760 2759 2804 +3 2760 2804 2805 +3 2760 2805 2806 +3 2761 2760 2806 +3 2762 2761 2806 +3 2762 2806 2807 +3 2762 2807 2808 +3 2763 2762 2808 +3 2764 2763 2808 +3 2764 2808 2809 +3 2764 2809 2810 +3 2765 2764 2810 +3 2766 2765 2810 +3 2766 2810 2811 +3 2766 2811 2812 +3 2767 2766 2812 +3 2768 2767 2812 +3 2768 2812 2813 +3 2768 2813 2633 +3 2769 2543 2814 +3 2770 2769 2814 +3 2770 2814 2815 +3 2770 2815 2816 +3 2771 2770 2816 +3 2772 2771 2816 +3 2772 2816 2817 +3 2772 2817 2818 +3 2773 2772 2818 +3 2774 2773 2818 +3 2774 2818 2819 +3 2774 2819 2820 +3 2775 2774 2820 +3 2776 2775 2820 +3 2776 2820 2821 +3 2776 2821 2822 +3 2777 2776 2822 +3 2778 2777 2822 +3 2778 2822 2823 +3 2778 2823 2824 +3 2779 2778 2824 +3 2780 2779 2824 +3 2780 2824 2825 +3 2780 2825 2826 +3 2781 2780 2826 +3 2782 2781 2826 +3 2782 2826 2827 +3 2782 2827 2828 +3 2783 2782 2828 +3 2784 2783 2828 +3 2784 2828 2829 +3 2784 2829 2830 +3 2785 2784 2830 +3 2786 2785 2830 +3 2786 2830 2831 +3 2786 2831 2832 +3 2787 2786 2832 +3 2788 2787 2832 +3 2788 2832 2833 +3 2788 2833 2834 +3 2789 2788 2834 +3 2790 2789 2834 +3 2790 2834 2835 +3 2790 2835 2836 +3 2791 2790 2836 +3 2792 2791 2836 +3 2792 2836 2837 +3 2792 2837 2838 +3 2793 2792 2838 +3 2794 2793 2838 +3 2794 2838 2839 +3 2794 2839 2840 +3 2795 2794 2840 +3 2796 2795 2840 +3 2796 2840 2841 +3 2796 2841 2842 +3 2797 2796 2842 +3 2798 2797 2842 +3 2798 2842 2843 +3 2798 2843 2844 +3 2799 2798 2844 +3 2800 2799 2844 +3 2800 2844 2845 +3 2800 2845 2846 +3 2801 2800 2846 +3 2802 2801 2846 +3 2802 2846 2847 +3 2802 2847 2848 +3 2803 2802 2848 +3 2804 2803 2848 +3 2804 2848 2849 +3 2804 2849 2850 +3 2805 2804 2850 +3 2806 2805 2850 +3 2806 2850 2851 +3 2806 2851 2852 +3 2807 2806 2852 +3 2808 2807 2852 +3 2808 2852 2853 +3 2808 2853 2854 +3 2809 2808 2854 +3 2810 2809 2854 +3 2810 2854 2855 +3 2810 2855 2856 +3 2811 2810 2856 +3 2812 2811 2856 +3 2812 2856 2857 +3 2812 2857 2858 +3 2813 2812 2858 +3 2633 2813 2858 +3 2814 2543 2859 +3 2814 2859 2860 +3 2815 2814 2860 +3 2816 2815 2860 +3 2816 2860 2861 +3 2816 2861 2862 +3 2817 2816 2862 +3 2818 2817 2862 +3 2818 2862 2863 +3 2818 2863 2864 +3 2819 2818 2864 +3 2820 2819 2864 +3 2820 2864 2865 +3 2820 2865 2866 +3 2821 2820 2866 +3 2822 2821 2866 +3 2822 2866 2867 +3 2822 2867 2868 +3 2823 2822 2868 +3 2824 2823 2868 +3 2824 2868 2869 +3 2824 2869 2870 +3 2825 2824 2870 +3 2826 2825 2870 +3 2826 2870 2871 +3 2826 2871 2872 +3 2827 2826 2872 +3 2828 2827 2872 +3 2828 2872 2873 +3 2828 2873 2874 +3 2829 2828 2874 +3 2830 2829 2874 +3 2830 2874 2875 +3 2830 2875 2876 +3 2831 2830 2876 +3 2832 2831 2876 +3 2832 2876 2877 +3 2832 2877 2878 +3 2833 2832 2878 +3 2834 2833 2878 +3 2834 2878 2879 +3 2834 2879 2880 +3 2835 2834 2880 +3 2836 2835 2880 +3 2836 2880 2881 +3 2836 2881 2882 +3 2837 2836 2882 +3 2838 2837 2882 +3 2838 2882 2883 +3 2838 2883 2884 +3 2839 2838 2884 +3 2840 2839 2884 +3 2840 2884 2885 +3 2840 2885 2886 +3 2841 2840 2886 +3 2842 2841 2886 +3 2842 2886 2887 +3 2842 2887 2888 +3 2843 2842 2888 +3 2844 2843 2888 +3 2844 2888 2889 +3 2844 2889 2890 +3 2845 2844 2890 +3 2846 2845 2890 +3 2846 2890 2891 +3 2846 2891 2892 +3 2847 2846 2892 +3 2848 2847 2892 +3 2848 2892 2893 +3 2848 2893 2894 +3 2849 2848 2894 +3 2850 2849 2894 +3 2850 2894 2895 +3 2850 2895 2896 +3 2851 2850 2896 +3 2852 2851 2896 +3 2852 2896 2897 +3 2852 2897 2898 +3 2853 2852 2898 +3 2854 2853 2898 +3 2854 2898 2899 +3 2854 2899 2900 +3 2855 2854 2900 +3 2856 2855 2900 +3 2856 2900 2901 +3 2856 2901 2902 +3 2857 2856 2902 +3 2858 2857 2902 +3 2858 2902 2903 +3 2858 2903 2633 +3 2859 2543 2542 +3 2860 2859 2542 +3 2860 2542 2546 +3 2860 2546 2547 +3 2861 2860 2547 +3 2862 2861 2547 +3 2862 2547 2550 +3 2862 2550 2551 +3 2863 2862 2551 +3 2864 2863 2551 +3 2864 2551 2554 +3 2864 2554 2555 +3 2865 2864 2555 +3 2866 2865 2555 +3 2866 2555 2558 +3 2866 2558 2559 +3 2867 2866 2559 +3 2868 2867 2559 +3 2868 2559 2562 +3 2868 2562 2563 +3 2869 2868 2563 +3 2870 2869 2563 +3 2870 2563 2566 +3 2870 2566 2567 +3 2871 2870 2567 +3 2872 2871 2567 +3 2872 2567 2570 +3 2872 2570 2571 +3 2873 2872 2571 +3 2874 2873 2571 +3 2874 2571 2574 +3 2874 2574 2575 +3 2875 2874 2575 +3 2876 2875 2575 +3 2876 2575 2578 +3 2876 2578 2579 +3 2877 2876 2579 +3 2878 2877 2579 +3 2878 2579 2582 +3 2878 2582 2583 +3 2879 2878 2583 +3 2880 2879 2583 +3 2880 2583 2586 +3 2880 2586 2587 +3 2881 2880 2587 +3 2882 2881 2587 +3 2882 2587 2590 +3 2882 2590 2591 +3 2883 2882 2591 +3 2884 2883 2591 +3 2884 2591 2594 +3 2884 2594 2595 +3 2885 2884 2595 +3 2886 2885 2595 +3 2886 2595 2598 +3 2886 2598 2599 +3 2887 2886 2599 +3 2888 2887 2599 +3 2888 2599 2602 +3 2888 2602 2603 +3 2889 2888 2603 +3 2890 2889 2603 +3 2890 2603 2606 +3 2890 2606 2607 +3 2891 2890 2607 +3 2892 2891 2607 +3 2892 2607 2610 +3 2892 2610 2611 +3 2893 2892 2611 +3 2894 2893 2611 +3 2894 2611 2614 +3 2894 2614 2615 +3 2895 2894 2615 +3 2896 2895 2615 +3 2896 2615 2618 +3 2896 2618 2619 +3 2897 2896 2619 +3 2898 2897 2619 +3 2898 2619 2622 +3 2898 2622 2623 +3 2899 2898 2623 +3 2900 2899 2623 +3 2900 2623 2626 +3 2900 2626 2627 +3 2901 2900 2627 +3 2902 2901 2627 +3 2902 2627 2630 +3 2902 2630 2631 +3 2903 2902 2631 +3 2633 2903 2631 +3 2904 2905 2906 +3 2904 2906 2907 +3 2908 2904 2907 +3 2909 2908 2907 +3 2909 2907 2910 +3 2909 2910 2911 +3 2912 2909 2911 +3 2913 2912 2911 +3 2913 2911 2914 +3 2913 2914 2915 +3 2916 2913 2915 +3 2917 2916 2915 +3 2917 2915 2918 +3 2917 2918 2919 +3 2920 2917 2919 +3 2921 2920 2919 +3 2921 2919 2922 +3 2921 2922 2923 +3 2924 2921 2923 +3 2925 2924 2923 +3 2925 2923 2926 +3 2925 2926 2927 +3 2928 2925 2927 +3 2929 2928 2927 +3 2929 2927 2930 +3 2929 2930 2931 +3 2932 2929 2931 +3 2933 2932 2931 +3 2933 2931 2934 +3 2933 2934 2935 +3 2936 2933 2935 +3 2937 2936 2935 +3 2937 2935 2938 +3 2937 2938 2939 +3 2940 2937 2939 +3 2941 2940 2939 +3 2941 2939 2942 +3 2941 2942 2943 +3 2944 2941 2943 +3 2945 2944 2943 +3 2945 2943 2946 +3 2945 2946 2947 +3 2948 2945 2947 +3 2949 2948 2947 +3 2949 2947 2950 +3 2949 2950 2951 +3 2952 2949 2951 +3 2953 2952 2951 +3 2953 2951 2954 +3 2953 2954 2955 +3 2956 2953 2955 +3 2957 2956 2955 +3 2957 2955 2958 +3 2957 2958 2959 +3 2960 2957 2959 +3 2961 2960 2959 +3 2961 2959 2962 +3 2961 2962 2963 +3 2964 2961 2963 +3 2965 2964 2963 +3 2965 2963 2966 +3 2965 2966 2967 +3 2968 2965 2967 +3 2969 2968 2967 +3 2969 2967 2970 +3 2969 2970 2971 +3 2972 2969 2971 +3 2973 2972 2971 +3 2973 2971 2974 +3 2973 2974 2975 +3 2976 2973 2975 +3 2977 2976 2975 +3 2977 2975 2978 +3 2977 2978 2979 +3 2980 2977 2979 +3 2981 2980 2979 +3 2981 2979 2982 +3 2981 2982 2983 +3 2984 2981 2983 +3 2985 2984 2983 +3 2985 2983 2986 +3 2985 2986 2987 +3 2988 2985 2987 +3 2989 2988 2987 +3 2989 2987 2990 +3 2989 2990 2991 +3 2992 2989 2991 +3 2993 2992 2991 +3 2993 2991 2994 +3 2993 2994 2995 +3 2906 2905 2996 +3 2907 2906 2996 +3 2907 2996 2997 +3 2907 2997 2998 +3 2910 2907 2998 +3 2911 2910 2998 +3 2911 2998 2999 +3 2911 2999 3000 +3 2914 2911 3000 +3 2915 2914 3000 +3 2915 3000 3001 +3 2915 3001 3002 +3 2918 2915 3002 +3 2919 2918 3002 +3 2919 3002 3003 +3 2919 3003 3004 +3 2922 2919 3004 +3 2923 2922 3004 +3 2923 3004 3005 +3 2923 3005 3006 +3 2926 2923 3006 +3 2927 2926 3006 +3 2927 3006 3007 +3 2927 3007 3008 +3 2930 2927 3008 +3 2931 2930 3008 +3 2931 3008 3009 +3 2931 3009 3010 +3 2934 2931 3010 +3 2935 2934 3010 +3 2935 3010 3011 +3 2935 3011 3012 +3 2938 2935 3012 +3 2939 2938 3012 +3 2939 3012 3013 +3 2939 3013 3014 +3 2942 2939 3014 +3 2943 2942 3014 +3 2943 3014 3015 +3 2943 3015 3016 +3 2946 2943 3016 +3 2947 2946 3016 +3 2947 3016 3017 +3 2947 3017 3018 +3 2950 2947 3018 +3 2951 2950 3018 +3 2951 3018 3019 +3 2951 3019 3020 +3 2954 2951 3020 +3 2955 2954 3020 +3 2955 3020 3021 +3 2955 3021 3022 +3 2958 2955 3022 +3 2959 2958 3022 +3 2959 3022 3023 +3 2959 3023 3024 +3 2962 2959 3024 +3 2963 2962 3024 +3 2963 3024 3025 +3 2963 3025 3026 +3 2966 2963 3026 +3 2967 2966 3026 +3 2967 3026 3027 +3 2967 3027 3028 +3 2970 2967 3028 +3 2971 2970 3028 +3 2971 3028 3029 +3 2971 3029 3030 +3 2974 2971 3030 +3 2975 2974 3030 +3 2975 3030 3031 +3 2975 3031 3032 +3 2978 2975 3032 +3 2979 2978 3032 +3 2979 3032 3033 +3 2979 3033 3034 +3 2982 2979 3034 +3 2983 2982 3034 +3 2983 3034 3035 +3 2983 3035 3036 +3 2986 2983 3036 +3 2987 2986 3036 +3 2987 3036 3037 +3 2987 3037 3038 +3 2990 2987 3038 +3 2991 2990 3038 +3 2991 3038 3039 +3 2991 3039 3040 +3 2994 2991 3040 +3 2995 2994 3040 +3 2996 2905 3041 +3 2996 3041 3042 +3 2997 2996 3042 +3 2998 2997 3042 +3 2998 3042 3043 +3 2998 3043 3044 +3 2999 2998 3044 +3 3000 2999 3044 +3 3000 3044 3045 +3 3000 3045 3046 +3 3001 3000 3046 +3 3002 3001 3046 +3 3002 3046 3047 +3 3002 3047 3048 +3 3003 3002 3048 +3 3004 3003 3048 +3 3004 3048 3049 +3 3004 3049 3050 +3 3005 3004 3050 +3 3006 3005 3050 +3 3006 3050 3051 +3 3006 3051 3052 +3 3007 3006 3052 +3 3008 3007 3052 +3 3008 3052 3053 +3 3008 3053 3054 +3 3009 3008 3054 +3 3010 3009 3054 +3 3010 3054 3055 +3 3010 3055 3056 +3 3011 3010 3056 +3 3012 3011 3056 +3 3012 3056 3057 +3 3012 3057 3058 +3 3013 3012 3058 +3 3014 3013 3058 +3 3014 3058 3059 +3 3014 3059 3060 +3 3015 3014 3060 +3 3016 3015 3060 +3 3016 3060 3061 +3 3016 3061 3062 +3 3017 3016 3062 +3 3018 3017 3062 +3 3018 3062 3063 +3 3018 3063 3064 +3 3019 3018 3064 +3 3020 3019 3064 +3 3020 3064 3065 +3 3020 3065 3066 +3 3021 3020 3066 +3 3022 3021 3066 +3 3022 3066 3067 +3 3022 3067 3068 +3 3023 3022 3068 +3 3024 3023 3068 +3 3024 3068 3069 +3 3024 3069 3070 +3 3025 3024 3070 +3 3026 3025 3070 +3 3026 3070 3071 +3 3026 3071 3072 +3 3027 3026 3072 +3 3028 3027 3072 +3 3028 3072 3073 +3 3028 3073 3074 +3 3029 3028 3074 +3 3030 3029 3074 +3 3030 3074 3075 +3 3030 3075 3076 +3 3031 3030 3076 +3 3032 3031 3076 +3 3032 3076 3077 +3 3032 3077 3078 +3 3033 3032 3078 +3 3034 3033 3078 +3 3034 3078 3079 +3 3034 3079 3080 +3 3035 3034 3080 +3 3036 3035 3080 +3 3036 3080 3081 +3 3036 3081 3082 +3 3037 3036 3082 +3 3038 3037 3082 +3 3038 3082 3083 +3 3038 3083 3084 +3 3039 3038 3084 +3 3040 3039 3084 +3 3040 3084 3085 +3 3040 3085 2995 +3 3041 2905 3086 +3 3042 3041 3086 +3 3042 3086 3087 +3 3042 3087 3088 +3 3043 3042 3088 +3 3044 3043 3088 +3 3044 3088 3089 +3 3044 3089 3090 +3 3045 3044 3090 +3 3046 3045 3090 +3 3046 3090 3091 +3 3046 3091 3092 +3 3047 3046 3092 +3 3048 3047 3092 +3 3048 3092 3093 +3 3048 3093 3094 +3 3049 3048 3094 +3 3050 3049 3094 +3 3050 3094 3095 +3 3050 3095 3096 +3 3051 3050 3096 +3 3052 3051 3096 +3 3052 3096 3097 +3 3052 3097 3098 +3 3053 3052 3098 +3 3054 3053 3098 +3 3054 3098 3099 +3 3054 3099 3100 +3 3055 3054 3100 +3 3056 3055 3100 +3 3056 3100 3101 +3 3056 3101 3102 +3 3057 3056 3102 +3 3058 3057 3102 +3 3058 3102 3103 +3 3058 3103 3104 +3 3059 3058 3104 +3 3060 3059 3104 +3 3060 3104 3105 +3 3060 3105 3106 +3 3061 3060 3106 +3 3062 3061 3106 +3 3062 3106 3107 +3 3062 3107 3108 +3 3063 3062 3108 +3 3064 3063 3108 +3 3064 3108 3109 +3 3064 3109 3110 +3 3065 3064 3110 +3 3066 3065 3110 +3 3066 3110 3111 +3 3066 3111 3112 +3 3067 3066 3112 +3 3068 3067 3112 +3 3068 3112 3113 +3 3068 3113 3114 +3 3069 3068 3114 +3 3070 3069 3114 +3 3070 3114 3115 +3 3070 3115 3116 +3 3071 3070 3116 +3 3072 3071 3116 +3 3072 3116 3117 +3 3072 3117 3118 +3 3073 3072 3118 +3 3074 3073 3118 +3 3074 3118 3119 +3 3074 3119 3120 +3 3075 3074 3120 +3 3076 3075 3120 +3 3076 3120 3121 +3 3076 3121 3122 +3 3077 3076 3122 +3 3078 3077 3122 +3 3078 3122 3123 +3 3078 3123 3124 +3 3079 3078 3124 +3 3080 3079 3124 +3 3080 3124 3125 +3 3080 3125 3126 +3 3081 3080 3126 +3 3082 3081 3126 +3 3082 3126 3127 +3 3082 3127 3128 +3 3083 3082 3128 +3 3084 3083 3128 +3 3084 3128 3129 +3 3084 3129 3130 +3 3085 3084 3130 +3 2995 3085 3130 +3 3086 2905 3131 +3 3086 3131 3132 +3 3087 3086 3132 +3 3088 3087 3132 +3 3088 3132 3133 +3 3088 3133 3134 +3 3089 3088 3134 +3 3090 3089 3134 +3 3090 3134 3135 +3 3090 3135 3136 +3 3091 3090 3136 +3 3092 3091 3136 +3 3092 3136 3137 +3 3092 3137 3138 +3 3093 3092 3138 +3 3094 3093 3138 +3 3094 3138 3139 +3 3094 3139 3140 +3 3095 3094 3140 +3 3096 3095 3140 +3 3096 3140 3141 +3 3096 3141 3142 +3 3097 3096 3142 +3 3098 3097 3142 +3 3098 3142 3143 +3 3098 3143 3144 +3 3099 3098 3144 +3 3100 3099 3144 +3 3100 3144 3145 +3 3100 3145 3146 +3 3101 3100 3146 +3 3102 3101 3146 +3 3102 3146 3147 +3 3102 3147 3148 +3 3103 3102 3148 +3 3104 3103 3148 +3 3104 3148 3149 +3 3104 3149 3150 +3 3105 3104 3150 +3 3106 3105 3150 +3 3106 3150 3151 +3 3106 3151 3152 +3 3107 3106 3152 +3 3108 3107 3152 +3 3108 3152 3153 +3 3108 3153 3154 +3 3109 3108 3154 +3 3110 3109 3154 +3 3110 3154 3155 +3 3110 3155 3156 +3 3111 3110 3156 +3 3112 3111 3156 +3 3112 3156 3157 +3 3112 3157 3158 +3 3113 3112 3158 +3 3114 3113 3158 +3 3114 3158 3159 +3 3114 3159 3160 +3 3115 3114 3160 +3 3116 3115 3160 +3 3116 3160 3161 +3 3116 3161 3162 +3 3117 3116 3162 +3 3118 3117 3162 +3 3118 3162 3163 +3 3118 3163 3164 +3 3119 3118 3164 +3 3120 3119 3164 +3 3120 3164 3165 +3 3120 3165 3166 +3 3121 3120 3166 +3 3122 3121 3166 +3 3122 3166 3167 +3 3122 3167 3168 +3 3123 3122 3168 +3 3124 3123 3168 +3 3124 3168 3169 +3 3124 3169 3170 +3 3125 3124 3170 +3 3126 3125 3170 +3 3126 3170 3171 +3 3126 3171 3172 +3 3127 3126 3172 +3 3128 3127 3172 +3 3128 3172 3173 +3 3128 3173 3174 +3 3129 3128 3174 +3 3130 3129 3174 +3 3130 3174 3175 +3 3130 3175 2995 +3 3131 2905 3176 +3 3132 3131 3176 +3 3132 3176 3177 +3 3132 3177 3178 +3 3133 3132 3178 +3 3134 3133 3178 +3 3134 3178 3179 +3 3134 3179 3180 +3 3135 3134 3180 +3 3136 3135 3180 +3 3136 3180 3181 +3 3136 3181 3182 +3 3137 3136 3182 +3 3138 3137 3182 +3 3138 3182 3183 +3 3138 3183 3184 +3 3139 3138 3184 +3 3140 3139 3184 +3 3140 3184 3185 +3 3140 3185 3186 +3 3141 3140 3186 +3 3142 3141 3186 +3 3142 3186 3187 +3 3142 3187 3188 +3 3143 3142 3188 +3 3144 3143 3188 +3 3144 3188 3189 +3 3144 3189 3190 +3 3145 3144 3190 +3 3146 3145 3190 +3 3146 3190 3191 +3 3146 3191 3192 +3 3147 3146 3192 +3 3148 3147 3192 +3 3148 3192 3193 +3 3148 3193 3194 +3 3149 3148 3194 +3 3150 3149 3194 +3 3150 3194 3195 +3 3150 3195 3196 +3 3151 3150 3196 +3 3152 3151 3196 +3 3152 3196 3197 +3 3152 3197 3198 +3 3153 3152 3198 +3 3154 3153 3198 +3 3154 3198 3199 +3 3154 3199 3200 +3 3155 3154 3200 +3 3156 3155 3200 +3 3156 3200 3201 +3 3156 3201 3202 +3 3157 3156 3202 +3 3158 3157 3202 +3 3158 3202 3203 +3 3158 3203 3204 +3 3159 3158 3204 +3 3160 3159 3204 +3 3160 3204 3205 +3 3160 3205 3206 +3 3161 3160 3206 +3 3162 3161 3206 +3 3162 3206 3207 +3 3162 3207 3208 +3 3163 3162 3208 +3 3164 3163 3208 +3 3164 3208 3209 +3 3164 3209 3210 +3 3165 3164 3210 +3 3166 3165 3210 +3 3166 3210 3211 +3 3166 3211 3212 +3 3167 3166 3212 +3 3168 3167 3212 +3 3168 3212 3213 +3 3168 3213 3214 +3 3169 3168 3214 +3 3170 3169 3214 +3 3170 3214 3215 +3 3170 3215 3216 +3 3171 3170 3216 +3 3172 3171 3216 +3 3172 3216 3217 +3 3172 3217 3218 +3 3173 3172 3218 +3 3174 3173 3218 +3 3174 3218 3219 +3 3174 3219 3220 +3 3175 3174 3220 +3 2995 3175 3220 +3 3176 2905 3221 +3 3176 3221 3222 +3 3177 3176 3222 +3 3178 3177 3222 +3 3178 3222 3223 +3 3178 3223 3224 +3 3179 3178 3224 +3 3180 3179 3224 +3 3180 3224 3225 +3 3180 3225 3226 +3 3181 3180 3226 +3 3182 3181 3226 +3 3182 3226 3227 +3 3182 3227 3228 +3 3183 3182 3228 +3 3184 3183 3228 +3 3184 3228 3229 +3 3184 3229 3230 +3 3185 3184 3230 +3 3186 3185 3230 +3 3186 3230 3231 +3 3186 3231 3232 +3 3187 3186 3232 +3 3188 3187 3232 +3 3188 3232 3233 +3 3188 3233 3234 +3 3189 3188 3234 +3 3190 3189 3234 +3 3190 3234 3235 +3 3190 3235 3236 +3 3191 3190 3236 +3 3192 3191 3236 +3 3192 3236 3237 +3 3192 3237 3238 +3 3193 3192 3238 +3 3194 3193 3238 +3 3194 3238 3239 +3 3194 3239 3240 +3 3195 3194 3240 +3 3196 3195 3240 +3 3196 3240 3241 +3 3196 3241 3242 +3 3197 3196 3242 +3 3198 3197 3242 +3 3198 3242 3243 +3 3198 3243 3244 +3 3199 3198 3244 +3 3200 3199 3244 +3 3200 3244 3245 +3 3200 3245 3246 +3 3201 3200 3246 +3 3202 3201 3246 +3 3202 3246 3247 +3 3202 3247 3248 +3 3203 3202 3248 +3 3204 3203 3248 +3 3204 3248 3249 +3 3204 3249 3250 +3 3205 3204 3250 +3 3206 3205 3250 +3 3206 3250 3251 +3 3206 3251 3252 +3 3207 3206 3252 +3 3208 3207 3252 +3 3208 3252 3253 +3 3208 3253 3254 +3 3209 3208 3254 +3 3210 3209 3254 +3 3210 3254 3255 +3 3210 3255 3256 +3 3211 3210 3256 +3 3212 3211 3256 +3 3212 3256 3257 +3 3212 3257 3258 +3 3213 3212 3258 +3 3214 3213 3258 +3 3214 3258 3259 +3 3214 3259 3260 +3 3215 3214 3260 +3 3216 3215 3260 +3 3216 3260 3261 +3 3216 3261 3262 +3 3217 3216 3262 +3 3218 3217 3262 +3 3218 3262 3263 +3 3218 3263 3264 +3 3219 3218 3264 +3 3220 3219 3264 +3 3220 3264 3265 +3 3220 3265 2995 +3 3221 2905 2904 +3 3222 3221 2904 +3 3222 2904 2908 +3 3222 2908 2909 +3 3223 3222 2909 +3 3224 3223 2909 +3 3224 2909 2912 +3 3224 2912 2913 +3 3225 3224 2913 +3 3226 3225 2913 +3 3226 2913 2916 +3 3226 2916 2917 +3 3227 3226 2917 +3 3228 3227 2917 +3 3228 2917 2920 +3 3228 2920 2921 +3 3229 3228 2921 +3 3230 3229 2921 +3 3230 2921 2924 +3 3230 2924 2925 +3 3231 3230 2925 +3 3232 3231 2925 +3 3232 2925 2928 +3 3232 2928 2929 +3 3233 3232 2929 +3 3234 3233 2929 +3 3234 2929 2932 +3 3234 2932 2933 +3 3235 3234 2933 +3 3236 3235 2933 +3 3236 2933 2936 +3 3236 2936 2937 +3 3237 3236 2937 +3 3238 3237 2937 +3 3238 2937 2940 +3 3238 2940 2941 +3 3239 3238 2941 +3 3240 3239 2941 +3 3240 2941 2944 +3 3240 2944 2945 +3 3241 3240 2945 +3 3242 3241 2945 +3 3242 2945 2948 +3 3242 2948 2949 +3 3243 3242 2949 +3 3244 3243 2949 +3 3244 2949 2952 +3 3244 2952 2953 +3 3245 3244 2953 +3 3246 3245 2953 +3 3246 2953 2956 +3 3246 2956 2957 +3 3247 3246 2957 +3 3248 3247 2957 +3 3248 2957 2960 +3 3248 2960 2961 +3 3249 3248 2961 +3 3250 3249 2961 +3 3250 2961 2964 +3 3250 2964 2965 +3 3251 3250 2965 +3 3252 3251 2965 +3 3252 2965 2968 +3 3252 2968 2969 +3 3253 3252 2969 +3 3254 3253 2969 +3 3254 2969 2972 +3 3254 2972 2973 +3 3255 3254 2973 +3 3256 3255 2973 +3 3256 2973 2976 +3 3256 2976 2977 +3 3257 3256 2977 +3 3258 3257 2977 +3 3258 2977 2980 +3 3258 2980 2981 +3 3259 3258 2981 +3 3260 3259 2981 +3 3260 2981 2984 +3 3260 2984 2985 +3 3261 3260 2985 +3 3262 3261 2985 +3 3262 2985 2988 +3 3262 2988 2989 +3 3263 3262 2989 +3 3264 3263 2989 +3 3264 2989 2992 +3 3264 2992 2993 +3 3265 3264 2993 +3 2995 3265 2993 +3 3266 3267 3268 +3 3266 3268 3269 +3 3270 3266 3269 +3 3271 3270 3269 +3 3271 3269 3272 +3 3271 3272 3273 +3 3274 3271 3273 +3 3275 3274 3273 +3 3275 3273 3276 +3 3275 3276 3277 +3 3278 3275 3277 +3 3279 3278 3277 +3 3279 3277 3280 +3 3279 3280 3281 +3 3282 3279 3281 +3 3283 3282 3281 +3 3283 3281 3284 +3 3283 3284 3285 +3 3286 3283 3285 +3 3287 3286 3285 +3 3287 3285 3288 +3 3287 3288 3289 +3 3290 3287 3289 +3 3291 3290 3289 +3 3291 3289 3292 +3 3291 3292 3293 +3 3294 3291 3293 +3 3295 3294 3293 +3 3295 3293 3296 +3 3295 3296 3297 +3 3298 3295 3297 +3 3299 3298 3297 +3 3299 3297 3300 +3 3299 3300 3301 +3 3302 3299 3301 +3 3303 3302 3301 +3 3303 3301 3304 +3 3303 3304 3305 +3 3306 3303 3305 +3 3307 3306 3305 +3 3307 3305 3308 +3 3307 3308 3309 +3 3310 3307 3309 +3 3311 3310 3309 +3 3311 3309 3312 +3 3311 3312 3313 +3 3314 3311 3313 +3 3315 3314 3313 +3 3315 3313 3316 +3 3315 3316 3317 +3 3318 3315 3317 +3 3319 3318 3317 +3 3319 3317 3320 +3 3319 3320 3321 +3 3322 3319 3321 +3 3323 3322 3321 +3 3323 3321 3324 +3 3323 3324 3325 +3 3326 3323 3325 +3 3327 3326 3325 +3 3327 3325 3328 +3 3327 3328 3329 +3 3330 3327 3329 +3 3331 3330 3329 +3 3331 3329 3332 +3 3331 3332 3333 +3 3334 3331 3333 +3 3335 3334 3333 +3 3335 3333 3336 +3 3335 3336 3337 +3 3338 3335 3337 +3 3339 3338 3337 +3 3339 3337 3340 +3 3339 3340 3341 +3 3342 3339 3341 +3 3343 3342 3341 +3 3343 3341 3344 +3 3343 3344 3345 +3 3346 3343 3345 +3 3347 3346 3345 +3 3347 3345 3348 +3 3347 3348 3349 +3 3350 3347 3349 +3 3351 3350 3349 +3 3351 3349 3352 +3 3351 3352 3353 +3 3354 3351 3353 +3 3355 3354 3353 +3 3355 3353 3356 +3 3355 3356 2995 +3 3268 3267 3357 +3 3269 3268 3357 +3 3269 3357 3358 +3 3269 3358 3359 +3 3272 3269 3359 +3 3273 3272 3359 +3 3273 3359 3360 +3 3273 3360 3361 +3 3276 3273 3361 +3 3277 3276 3361 +3 3277 3361 3362 +3 3277 3362 3363 +3 3280 3277 3363 +3 3281 3280 3363 +3 3281 3363 3364 +3 3281 3364 3365 +3 3284 3281 3365 +3 3285 3284 3365 +3 3285 3365 3366 +3 3285 3366 3367 +3 3288 3285 3367 +3 3289 3288 3367 +3 3289 3367 3368 +3 3289 3368 3369 +3 3292 3289 3369 +3 3293 3292 3369 +3 3293 3369 3370 +3 3293 3370 3371 +3 3296 3293 3371 +3 3297 3296 3371 +3 3297 3371 3372 +3 3297 3372 3373 +3 3300 3297 3373 +3 3301 3300 3373 +3 3301 3373 3374 +3 3301 3374 3375 +3 3304 3301 3375 +3 3305 3304 3375 +3 3305 3375 3376 +3 3305 3376 3377 +3 3308 3305 3377 +3 3309 3308 3377 +3 3309 3377 3378 +3 3309 3378 3379 +3 3312 3309 3379 +3 3313 3312 3379 +3 3313 3379 3380 +3 3313 3380 3381 +3 3316 3313 3381 +3 3317 3316 3381 +3 3317 3381 3382 +3 3317 3382 3383 +3 3320 3317 3383 +3 3321 3320 3383 +3 3321 3383 3384 +3 3321 3384 3385 +3 3324 3321 3385 +3 3325 3324 3385 +3 3325 3385 3386 +3 3325 3386 3387 +3 3328 3325 3387 +3 3329 3328 3387 +3 3329 3387 3388 +3 3329 3388 3389 +3 3332 3329 3389 +3 3333 3332 3389 +3 3333 3389 3390 +3 3333 3390 3391 +3 3336 3333 3391 +3 3337 3336 3391 +3 3337 3391 3392 +3 3337 3392 3393 +3 3340 3337 3393 +3 3341 3340 3393 +3 3341 3393 3394 +3 3341 3394 3395 +3 3344 3341 3395 +3 3345 3344 3395 +3 3345 3395 3396 +3 3345 3396 3397 +3 3348 3345 3397 +3 3349 3348 3397 +3 3349 3397 3398 +3 3349 3398 3399 +3 3352 3349 3399 +3 3353 3352 3399 +3 3353 3399 3400 +3 3353 3400 3401 +3 3356 3353 3401 +3 2995 3356 3401 +3 3357 3267 3402 +3 3357 3402 3403 +3 3358 3357 3403 +3 3359 3358 3403 +3 3359 3403 3404 +3 3359 3404 3405 +3 3360 3359 3405 +3 3361 3360 3405 +3 3361 3405 3406 +3 3361 3406 3407 +3 3362 3361 3407 +3 3363 3362 3407 +3 3363 3407 3408 +3 3363 3408 3409 +3 3364 3363 3409 +3 3365 3364 3409 +3 3365 3409 3410 +3 3365 3410 3411 +3 3366 3365 3411 +3 3367 3366 3411 +3 3367 3411 3412 +3 3367 3412 3413 +3 3368 3367 3413 +3 3369 3368 3413 +3 3369 3413 3414 +3 3369 3414 3415 +3 3370 3369 3415 +3 3371 3370 3415 +3 3371 3415 3416 +3 3371 3416 3417 +3 3372 3371 3417 +3 3373 3372 3417 +3 3373 3417 3418 +3 3373 3418 3419 +3 3374 3373 3419 +3 3375 3374 3419 +3 3375 3419 3420 +3 3375 3420 3421 +3 3376 3375 3421 +3 3377 3376 3421 +3 3377 3421 3422 +3 3377 3422 3423 +3 3378 3377 3423 +3 3379 3378 3423 +3 3379 3423 3424 +3 3379 3424 3425 +3 3380 3379 3425 +3 3381 3380 3425 +3 3381 3425 3426 +3 3381 3426 3427 +3 3382 3381 3427 +3 3383 3382 3427 +3 3383 3427 3428 +3 3383 3428 3429 +3 3384 3383 3429 +3 3385 3384 3429 +3 3385 3429 3430 +3 3385 3430 3431 +3 3386 3385 3431 +3 3387 3386 3431 +3 3387 3431 3432 +3 3387 3432 3433 +3 3388 3387 3433 +3 3389 3388 3433 +3 3389 3433 3434 +3 3389 3434 3435 +3 3390 3389 3435 +3 3391 3390 3435 +3 3391 3435 3436 +3 3391 3436 3437 +3 3392 3391 3437 +3 3393 3392 3437 +3 3393 3437 3438 +3 3393 3438 3439 +3 3394 3393 3439 +3 3395 3394 3439 +3 3395 3439 3440 +3 3395 3440 3441 +3 3396 3395 3441 +3 3397 3396 3441 +3 3397 3441 3442 +3 3397 3442 3443 +3 3398 3397 3443 +3 3399 3398 3443 +3 3399 3443 3444 +3 3399 3444 3445 +3 3400 3399 3445 +3 3401 3400 3445 +3 3401 3445 3446 +3 3401 3446 2995 +3 3402 3267 3447 +3 3403 3402 3447 +3 3403 3447 3448 +3 3403 3448 3449 +3 3404 3403 3449 +3 3405 3404 3449 +3 3405 3449 3450 +3 3405 3450 3451 +3 3406 3405 3451 +3 3407 3406 3451 +3 3407 3451 3452 +3 3407 3452 3453 +3 3408 3407 3453 +3 3409 3408 3453 +3 3409 3453 3454 +3 3409 3454 3455 +3 3410 3409 3455 +3 3411 3410 3455 +3 3411 3455 3456 +3 3411 3456 3457 +3 3412 3411 3457 +3 3413 3412 3457 +3 3413 3457 3458 +3 3413 3458 3459 +3 3414 3413 3459 +3 3415 3414 3459 +3 3415 3459 3460 +3 3415 3460 3461 +3 3416 3415 3461 +3 3417 3416 3461 +3 3417 3461 3462 +3 3417 3462 3463 +3 3418 3417 3463 +3 3419 3418 3463 +3 3419 3463 3464 +3 3419 3464 3465 +3 3420 3419 3465 +3 3421 3420 3465 +3 3421 3465 3466 +3 3421 3466 3467 +3 3422 3421 3467 +3 3423 3422 3467 +3 3423 3467 3468 +3 3423 3468 3469 +3 3424 3423 3469 +3 3425 3424 3469 +3 3425 3469 3470 +3 3425 3470 3471 +3 3426 3425 3471 +3 3427 3426 3471 +3 3427 3471 3472 +3 3427 3472 3473 +3 3428 3427 3473 +3 3429 3428 3473 +3 3429 3473 3474 +3 3429 3474 3475 +3 3430 3429 3475 +3 3431 3430 3475 +3 3431 3475 3476 +3 3431 3476 3477 +3 3432 3431 3477 +3 3433 3432 3477 +3 3433 3477 3478 +3 3433 3478 3479 +3 3434 3433 3479 +3 3435 3434 3479 +3 3435 3479 3480 +3 3435 3480 3481 +3 3436 3435 3481 +3 3437 3436 3481 +3 3437 3481 3482 +3 3437 3482 3483 +3 3438 3437 3483 +3 3439 3438 3483 +3 3439 3483 3484 +3 3439 3484 3485 +3 3440 3439 3485 +3 3441 3440 3485 +3 3441 3485 3486 +3 3441 3486 3487 +3 3442 3441 3487 +3 3443 3442 3487 +3 3443 3487 3488 +3 3443 3488 3489 +3 3444 3443 3489 +3 3445 3444 3489 +3 3445 3489 3490 +3 3445 3490 3491 +3 3446 3445 3491 +3 2995 3446 3491 +3 3447 3267 3492 +3 3447 3492 3493 +3 3448 3447 3493 +3 3449 3448 3493 +3 3449 3493 3494 +3 3449 3494 3495 +3 3450 3449 3495 +3 3451 3450 3495 +3 3451 3495 3496 +3 3451 3496 3497 +3 3452 3451 3497 +3 3453 3452 3497 +3 3453 3497 3498 +3 3453 3498 3499 +3 3454 3453 3499 +3 3455 3454 3499 +3 3455 3499 3500 +3 3455 3500 3501 +3 3456 3455 3501 +3 3457 3456 3501 +3 3457 3501 3502 +3 3457 3502 3503 +3 3458 3457 3503 +3 3459 3458 3503 +3 3459 3503 3504 +3 3459 3504 3505 +3 3460 3459 3505 +3 3461 3460 3505 +3 3461 3505 3506 +3 3461 3506 3507 +3 3462 3461 3507 +3 3463 3462 3507 +3 3463 3507 3508 +3 3463 3508 3509 +3 3464 3463 3509 +3 3465 3464 3509 +3 3465 3509 3510 +3 3465 3510 3511 +3 3466 3465 3511 +3 3467 3466 3511 +3 3467 3511 3512 +3 3467 3512 3513 +3 3468 3467 3513 +3 3469 3468 3513 +3 3469 3513 3514 +3 3469 3514 3515 +3 3470 3469 3515 +3 3471 3470 3515 +3 3471 3515 3516 +3 3471 3516 3517 +3 3472 3471 3517 +3 3473 3472 3517 +3 3473 3517 3518 +3 3473 3518 3519 +3 3474 3473 3519 +3 3475 3474 3519 +3 3475 3519 3520 +3 3475 3520 3521 +3 3476 3475 3521 +3 3477 3476 3521 +3 3477 3521 3522 +3 3477 3522 3523 +3 3478 3477 3523 +3 3479 3478 3523 +3 3479 3523 3524 +3 3479 3524 3525 +3 3480 3479 3525 +3 3481 3480 3525 +3 3481 3525 3526 +3 3481 3526 3527 +3 3482 3481 3527 +3 3483 3482 3527 +3 3483 3527 3528 +3 3483 3528 3529 +3 3484 3483 3529 +3 3485 3484 3529 +3 3485 3529 3530 +3 3485 3530 3531 +3 3486 3485 3531 +3 3487 3486 3531 +3 3487 3531 3532 +3 3487 3532 3533 +3 3488 3487 3533 +3 3489 3488 3533 +3 3489 3533 3534 +3 3489 3534 3535 +3 3490 3489 3535 +3 3491 3490 3535 +3 3491 3535 3536 +3 3491 3536 2995 +3 3492 3267 3537 +3 3493 3492 3537 +3 3493 3537 3538 +3 3493 3538 3539 +3 3494 3493 3539 +3 3495 3494 3539 +3 3495 3539 3540 +3 3495 3540 3541 +3 3496 3495 3541 +3 3497 3496 3541 +3 3497 3541 3542 +3 3497 3542 3543 +3 3498 3497 3543 +3 3499 3498 3543 +3 3499 3543 3544 +3 3499 3544 3545 +3 3500 3499 3545 +3 3501 3500 3545 +3 3501 3545 3546 +3 3501 3546 3547 +3 3502 3501 3547 +3 3503 3502 3547 +3 3503 3547 3548 +3 3503 3548 3549 +3 3504 3503 3549 +3 3505 3504 3549 +3 3505 3549 3550 +3 3505 3550 3551 +3 3506 3505 3551 +3 3507 3506 3551 +3 3507 3551 3552 +3 3507 3552 3553 +3 3508 3507 3553 +3 3509 3508 3553 +3 3509 3553 3554 +3 3509 3554 3555 +3 3510 3509 3555 +3 3511 3510 3555 +3 3511 3555 3556 +3 3511 3556 3557 +3 3512 3511 3557 +3 3513 3512 3557 +3 3513 3557 3558 +3 3513 3558 3559 +3 3514 3513 3559 +3 3515 3514 3559 +3 3515 3559 3560 +3 3515 3560 3561 +3 3516 3515 3561 +3 3517 3516 3561 +3 3517 3561 3562 +3 3517 3562 3563 +3 3518 3517 3563 +3 3519 3518 3563 +3 3519 3563 3564 +3 3519 3564 3565 +3 3520 3519 3565 +3 3521 3520 3565 +3 3521 3565 3566 +3 3521 3566 3567 +3 3522 3521 3567 +3 3523 3522 3567 +3 3523 3567 3568 +3 3523 3568 3569 +3 3524 3523 3569 +3 3525 3524 3569 +3 3525 3569 3570 +3 3525 3570 3571 +3 3526 3525 3571 +3 3527 3526 3571 +3 3527 3571 3572 +3 3527 3572 3573 +3 3528 3527 3573 +3 3529 3528 3573 +3 3529 3573 3574 +3 3529 3574 3575 +3 3530 3529 3575 +3 3531 3530 3575 +3 3531 3575 3576 +3 3531 3576 3577 +3 3532 3531 3577 +3 3533 3532 3577 +3 3533 3577 3578 +3 3533 3578 3579 +3 3534 3533 3579 +3 3535 3534 3579 +3 3535 3579 3580 +3 3535 3580 3581 +3 3536 3535 3581 +3 2995 3536 3581 +3 3537 3267 3582 +3 3537 3582 3583 +3 3538 3537 3583 +3 3539 3538 3583 +3 3539 3583 3584 +3 3539 3584 3585 +3 3540 3539 3585 +3 3541 3540 3585 +3 3541 3585 3586 +3 3541 3586 3587 +3 3542 3541 3587 +3 3543 3542 3587 +3 3543 3587 3588 +3 3543 3588 3589 +3 3544 3543 3589 +3 3545 3544 3589 +3 3545 3589 3590 +3 3545 3590 3591 +3 3546 3545 3591 +3 3547 3546 3591 +3 3547 3591 3592 +3 3547 3592 3593 +3 3548 3547 3593 +3 3549 3548 3593 +3 3549 3593 3594 +3 3549 3594 3595 +3 3550 3549 3595 +3 3551 3550 3595 +3 3551 3595 3596 +3 3551 3596 3597 +3 3552 3551 3597 +3 3553 3552 3597 +3 3553 3597 3598 +3 3553 3598 3599 +3 3554 3553 3599 +3 3555 3554 3599 +3 3555 3599 3600 +3 3555 3600 3601 +3 3556 3555 3601 +3 3557 3556 3601 +3 3557 3601 3602 +3 3557 3602 3603 +3 3558 3557 3603 +3 3559 3558 3603 +3 3559 3603 3604 +3 3559 3604 3605 +3 3560 3559 3605 +3 3561 3560 3605 +3 3561 3605 3606 +3 3561 3606 3607 +3 3562 3561 3607 +3 3563 3562 3607 +3 3563 3607 3608 +3 3563 3608 3609 +3 3564 3563 3609 +3 3565 3564 3609 +3 3565 3609 3610 +3 3565 3610 3611 +3 3566 3565 3611 +3 3567 3566 3611 +3 3567 3611 3612 +3 3567 3612 3613 +3 3568 3567 3613 +3 3569 3568 3613 +3 3569 3613 3614 +3 3569 3614 3615 +3 3570 3569 3615 +3 3571 3570 3615 +3 3571 3615 3616 +3 3571 3616 3617 +3 3572 3571 3617 +3 3573 3572 3617 +3 3573 3617 3618 +3 3573 3618 3619 +3 3574 3573 3619 +3 3575 3574 3619 +3 3575 3619 3620 +3 3575 3620 3621 +3 3576 3575 3621 +3 3577 3576 3621 +3 3577 3621 3622 +3 3577 3622 3623 +3 3578 3577 3623 +3 3579 3578 3623 +3 3579 3623 3624 +3 3579 3624 3625 +3 3580 3579 3625 +3 3581 3580 3625 +3 3581 3625 3626 +3 3581 3626 2995 +3 3582 3267 3266 +3 3583 3582 3266 +3 3583 3266 3270 +3 3583 3270 3271 +3 3584 3583 3271 +3 3585 3584 3271 +3 3585 3271 3274 +3 3585 3274 3275 +3 3586 3585 3275 +3 3587 3586 3275 +3 3587 3275 3278 +3 3587 3278 3279 +3 3588 3587 3279 +3 3589 3588 3279 +3 3589 3279 3282 +3 3589 3282 3283 +3 3590 3589 3283 +3 3591 3590 3283 +3 3591 3283 3286 +3 3591 3286 3287 +3 3592 3591 3287 +3 3593 3592 3287 +3 3593 3287 3290 +3 3593 3290 3291 +3 3594 3593 3291 +3 3595 3594 3291 +3 3595 3291 3294 +3 3595 3294 3295 +3 3596 3595 3295 +3 3597 3596 3295 +3 3597 3295 3298 +3 3597 3298 3299 +3 3598 3597 3299 +3 3599 3598 3299 +3 3599 3299 3302 +3 3599 3302 3303 +3 3600 3599 3303 +3 3601 3600 3303 +3 3601 3303 3306 +3 3601 3306 3307 +3 3602 3601 3307 +3 3603 3602 3307 +3 3603 3307 3310 +3 3603 3310 3311 +3 3604 3603 3311 +3 3605 3604 3311 +3 3605 3311 3314 +3 3605 3314 3315 +3 3606 3605 3315 +3 3607 3606 3315 +3 3607 3315 3318 +3 3607 3318 3319 +3 3608 3607 3319 +3 3609 3608 3319 +3 3609 3319 3322 +3 3609 3322 3323 +3 3610 3609 3323 +3 3611 3610 3323 +3 3611 3323 3326 +3 3611 3326 3327 +3 3612 3611 3327 +3 3613 3612 3327 +3 3613 3327 3330 +3 3613 3330 3331 +3 3614 3613 3331 +3 3615 3614 3331 +3 3615 3331 3334 +3 3615 3334 3335 +3 3616 3615 3335 +3 3617 3616 3335 +3 3617 3335 3338 +3 3617 3338 3339 +3 3618 3617 3339 +3 3619 3618 3339 +3 3619 3339 3342 +3 3619 3342 3343 +3 3620 3619 3343 +3 3621 3620 3343 +3 3621 3343 3346 +3 3621 3346 3347 +3 3622 3621 3347 +3 3623 3622 3347 +3 3623 3347 3350 +3 3623 3350 3351 +3 3624 3623 3351 +3 3625 3624 3351 +3 3625 3351 3354 +3 3625 3354 3355 +3 3626 3625 3355 +3 2995 3626 3355 +3 3627 3628 3629 +3 3627 3629 3630 +3 3631 3627 3630 +3 3632 3631 3630 +3 3632 3630 3633 +3 3632 3633 3634 +3 3635 3632 3634 +3 3636 3635 3634 +3 3636 3634 3637 +3 3636 3637 3638 +3 3639 3636 3638 +3 3640 3639 3638 +3 3640 3638 3641 +3 3640 3641 3642 +3 3643 3640 3642 +3 3644 3643 3642 +3 3644 3642 3645 +3 3644 3645 3646 +3 3647 3644 3646 +3 3648 3647 3646 +3 3648 3646 3649 +3 3648 3649 3650 +3 3651 3650 3652 +3 3651 3652 3653 +3 3654 3651 3653 +3 3655 3654 3653 +3 3655 3653 3656 +3 3655 3656 3657 +3 3658 3655 3657 +3 3659 3658 3657 +3 3659 3657 3660 +3 3659 3660 3661 +3 3662 3659 3661 +3 3663 3662 3661 +3 3663 3661 3664 +3 3663 3664 3665 +3 3666 3663 3665 +3 3667 3666 3665 +3 3667 3665 3668 +3 3667 3668 3669 +3 3670 3667 3669 +3 3671 3670 3669 +3 3671 3669 3672 +3 3671 3672 3673 +3 3674 3671 3673 +3 3675 3674 3673 +3 3675 3673 3676 +3 3675 3676 3677 +3 3678 3675 3677 +3 3679 3678 3677 +3 3679 3677 3680 +3 3679 3680 3681 +3 3682 3679 3681 +3 3683 3682 3681 +3 3683 3681 3684 +3 3683 3684 3685 +3 3686 3683 3685 +3 3687 3686 3685 +3 3628 3688 3689 +3 3628 3689 3690 +3 3629 3628 3690 +3 3630 3629 3690 +3 3630 3690 3691 +3 3630 3691 3692 +3 3633 3630 3692 +3 3634 3633 3692 +3 3634 3692 3693 +3 3634 3693 3694 +3 3637 3634 3694 +3 3638 3637 3694 +3 3638 3694 3695 +3 3638 3695 3696 +3 3641 3638 3696 +3 3642 3641 3696 +3 3642 3696 3697 +3 3642 3697 3698 +3 3645 3642 3698 +3 3646 3645 3698 +3 3646 3698 3699 +3 3646 3699 3700 +3 3649 3646 3700 +3 3650 3649 3700 +3 3650 3700 3701 +3 3650 3701 3702 +3 3652 3650 3702 +3 3653 3652 3702 +3 3653 3702 3703 +3 3653 3703 3704 +3 3656 3653 3704 +3 3657 3656 3704 +3 3657 3704 3705 +3 3657 3705 3706 +3 3660 3657 3706 +3 3661 3660 3706 +3 3661 3706 3707 +3 3661 3707 3708 +3 3664 3661 3708 +3 3665 3664 3708 +3 3665 3708 3709 +3 3665 3709 3710 +3 3668 3665 3710 +3 3669 3668 3710 +3 3669 3710 3711 +3 3669 3711 3712 +3 3672 3669 3712 +3 3673 3672 3712 +3 3673 3712 3713 +3 3673 3713 3714 +3 3676 3673 3714 +3 3677 3676 3714 +3 3677 3714 3715 +3 3677 3715 3716 +3 3680 3677 3716 +3 3681 3680 3716 +3 3681 3716 3717 +3 3681 3717 3718 +3 3684 3681 3718 +3 3685 3684 3718 +3 3685 3718 3719 +3 3685 3719 3720 +3 3687 3685 3720 +3 3721 3687 3720 +3 3689 3688 3722 +3 3690 3689 3722 +3 3690 3722 3723 +3 3690 3723 3724 +3 3691 3690 3724 +3 3692 3691 3724 +3 3692 3724 3725 +3 3692 3725 3726 +3 3693 3692 3726 +3 3694 3693 3726 +3 3694 3726 3727 +3 3694 3727 3728 +3 3695 3694 3728 +3 3696 3695 3728 +3 3696 3728 3729 +3 3696 3729 3730 +3 3697 3696 3730 +3 3698 3697 3730 +3 3698 3730 3731 +3 3698 3731 3732 +3 3699 3698 3732 +3 3700 3699 3732 +3 3700 3732 3733 +3 3700 3733 3701 +3 3702 3701 3734 +3 3702 3734 3735 +3 3703 3702 3735 +3 3704 3703 3735 +3 3704 3735 3736 +3 3704 3736 3737 +3 3705 3704 3737 +3 3706 3705 3737 +3 3706 3737 3738 +3 3706 3738 3739 +3 3707 3706 3739 +3 3708 3707 3739 +3 3708 3739 3740 +3 3708 3740 3741 +3 3709 3708 3741 +3 3710 3709 3741 +3 3710 3741 3742 +3 3710 3742 3743 +3 3711 3710 3743 +3 3712 3711 3743 +3 3712 3743 3744 +3 3712 3744 3745 +3 3713 3712 3745 +3 3714 3713 3745 +3 3714 3745 3746 +3 3714 3746 3747 +3 3715 3714 3747 +3 3716 3715 3747 +3 3716 3747 3748 +3 3716 3748 3749 +3 3717 3716 3749 +3 3718 3717 3749 +3 3718 3749 3750 +3 3718 3750 3751 +3 3719 3718 3751 +3 3720 3719 3751 +3 3720 3751 3752 +3 3720 3752 3721 +3 3723 3722 3753 +3 3724 3723 3753 +3 3724 3753 3754 +3 3724 3754 3755 +3 3725 3724 3755 +3 3726 3725 3755 +3 3726 3755 3756 +3 3726 3756 3757 +3 3727 3726 3757 +3 3728 3727 3757 +3 3728 3757 3758 +3 3728 3758 3759 +3 3729 3728 3759 +3 3730 3729 3759 +3 3730 3759 3760 +3 3730 3760 3761 +3 3731 3730 3761 +3 3732 3731 3761 +3 3732 3761 3762 +3 3732 3762 3763 +3 3733 3732 3763 +3 3701 3733 3763 +3 3734 3701 3764 +3 3735 3734 3764 +3 3735 3764 3765 +3 3735 3765 3766 +3 3736 3735 3766 +3 3737 3736 3766 +3 3737 3766 3767 +3 3737 3767 3768 +3 3738 3737 3768 +3 3739 3738 3768 +3 3739 3768 3769 +3 3739 3769 3770 +3 3740 3739 3770 +3 3741 3740 3770 +3 3741 3770 3771 +3 3741 3771 3772 +3 3742 3741 3772 +3 3743 3742 3772 +3 3743 3772 3773 +3 3743 3773 3774 +3 3744 3743 3774 +3 3745 3744 3774 +3 3745 3774 3775 +3 3745 3775 3776 +3 3746 3745 3776 +3 3747 3746 3776 +3 3747 3776 3777 +3 3747 3777 3778 +3 3748 3747 3778 +3 3749 3748 3778 +3 3749 3778 3779 +3 3749 3779 3780 +3 3750 3749 3780 +3 3751 3750 3780 +3 3751 3780 3781 +3 3751 3781 3782 +3 3752 3751 3782 +3 3721 3752 3782 +3 3722 3688 3783 +3 3753 3722 3783 +3 3753 3783 3784 +3 3753 3784 3785 +3 3754 3753 3785 +3 3755 3754 3785 +3 3755 3785 3786 +3 3755 3786 3787 +3 3756 3755 3787 +3 3757 3756 3787 +3 3757 3787 3788 +3 3757 3788 3789 +3 3758 3757 3789 +3 3759 3758 3789 +3 3759 3789 3790 +3 3759 3790 3791 +3 3760 3759 3791 +3 3761 3760 3791 +3 3761 3791 3792 +3 3761 3792 3793 +3 3762 3761 3793 +3 3763 3762 3793 +3 3763 3793 3794 +3 3763 3794 3795 +3 3701 3763 3795 +3 3764 3701 3795 +3 3764 3795 3796 +3 3764 3796 3797 +3 3765 3764 3797 +3 3766 3765 3797 +3 3766 3797 3798 +3 3766 3798 3799 +3 3767 3766 3799 +3 3768 3767 3799 +3 3768 3799 3800 +3 3768 3800 3801 +3 3769 3768 3801 +3 3770 3769 3801 +3 3770 3801 3802 +3 3770 3802 3803 +3 3771 3770 3803 +3 3772 3771 3803 +3 3772 3803 3804 +3 3772 3804 3805 +3 3773 3772 3805 +3 3774 3773 3805 +3 3774 3805 3806 +3 3774 3806 3807 +3 3775 3774 3807 +3 3776 3775 3807 +3 3776 3807 3808 +3 3776 3808 3809 +3 3777 3776 3809 +3 3778 3777 3809 +3 3778 3809 3810 +3 3778 3810 3811 +3 3779 3778 3811 +3 3780 3779 3811 +3 3780 3811 3812 +3 3780 3812 3813 +3 3781 3780 3813 +3 3782 3781 3813 +3 3782 3813 3814 +3 3782 3814 3721 +3 3784 3783 3815 +3 3785 3784 3815 +3 3785 3815 3816 +3 3785 3816 3817 +3 3786 3785 3817 +3 3787 3786 3817 +3 3787 3817 3818 +3 3787 3818 3819 +3 3788 3787 3819 +3 3789 3788 3819 +3 3789 3819 3820 +3 3789 3820 3821 +3 3790 3789 3821 +3 3791 3790 3821 +3 3791 3821 3822 +3 3791 3822 3823 +3 3792 3791 3823 +3 3793 3792 3823 +3 3793 3823 3824 +3 3793 3824 3825 +3 3794 3793 3825 +3 3795 3794 3825 +3 3795 3825 3826 +3 3795 3826 3827 +3 3796 3795 3827 +3 3797 3796 3827 +3 3797 3827 3828 +3 3797 3828 3829 +3 3798 3797 3829 +3 3799 3798 3829 +3 3799 3829 3830 +3 3799 3830 3831 +3 3800 3799 3831 +3 3801 3800 3831 +3 3801 3831 3832 +3 3801 3832 3833 +3 3802 3801 3833 +3 3803 3802 3833 +3 3803 3833 3834 +3 3803 3834 3835 +3 3804 3803 3835 +3 3805 3804 3835 +3 3805 3835 3836 +3 3805 3836 3837 +3 3806 3805 3837 +3 3807 3806 3837 +3 3807 3837 3838 +3 3807 3838 3839 +3 3808 3807 3839 +3 3809 3808 3839 +3 3809 3839 3840 +3 3809 3840 3841 +3 3810 3809 3841 +3 3811 3810 3841 +3 3811 3841 3842 +3 3811 3842 3843 +3 3812 3811 3843 +3 3813 3812 3843 +3 3813 3843 3844 +3 3813 3844 3845 +3 3814 3813 3845 +3 3721 3814 3845 +3 3783 3688 3846 +3 3815 3783 3846 +3 3815 3846 3847 +3 3815 3847 3848 +3 3816 3815 3848 +3 3817 3816 3848 +3 3817 3848 3849 +3 3817 3849 3850 +3 3818 3817 3850 +3 3819 3818 3850 +3 3819 3850 3851 +3 3819 3851 3852 +3 3820 3819 3852 +3 3821 3820 3852 +3 3821 3852 3853 +3 3821 3853 3854 +3 3822 3821 3854 +3 3823 3822 3854 +3 3823 3854 3855 +3 3823 3855 3856 +3 3824 3823 3856 +3 3825 3824 3856 +3 3825 3856 3857 +3 3825 3857 3858 +3 3826 3825 3858 +3 3827 3826 3858 +3 3827 3858 3859 +3 3827 3859 3860 +3 3828 3827 3860 +3 3829 3828 3860 +3 3829 3860 3861 +3 3829 3861 3862 +3 3830 3829 3862 +3 3831 3830 3862 +3 3831 3862 3863 +3 3831 3863 3864 +3 3832 3831 3864 +3 3833 3832 3864 +3 3833 3864 3865 +3 3833 3865 3866 +3 3834 3833 3866 +3 3835 3834 3866 +3 3835 3866 3867 +3 3835 3867 3868 +3 3836 3835 3868 +3 3837 3836 3868 +3 3837 3868 3869 +3 3837 3869 3870 +3 3838 3837 3870 +3 3839 3838 3870 +3 3839 3870 3871 +3 3839 3871 3872 +3 3840 3839 3872 +3 3841 3840 3872 +3 3841 3872 3873 +3 3841 3873 3874 +3 3842 3841 3874 +3 3843 3842 3874 +3 3843 3874 3875 +3 3843 3875 3876 +3 3844 3843 3876 +3 3845 3844 3876 +3 3845 3876 3877 +3 3845 3877 3721 +3 3847 3846 3878 +3 3848 3847 3878 +3 3848 3878 3879 +3 3848 3879 3880 +3 3849 3848 3880 +3 3850 3849 3880 +3 3850 3880 3881 +3 3850 3881 3882 +3 3851 3850 3882 +3 3852 3851 3882 +3 3852 3882 3883 +3 3852 3883 3884 +3 3853 3852 3884 +3 3854 3853 3884 +3 3854 3884 3885 +3 3854 3885 3886 +3 3855 3854 3886 +3 3856 3855 3886 +3 3856 3886 3887 +3 3856 3887 3888 +3 3857 3856 3888 +3 3858 3857 3888 +3 3859 3858 3889 +3 3860 3859 3889 +3 3860 3889 3890 +3 3860 3890 3891 +3 3861 3860 3891 +3 3862 3861 3891 +3 3862 3891 3892 +3 3862 3892 3893 +3 3863 3862 3893 +3 3864 3863 3893 +3 3864 3893 3894 +3 3864 3894 3895 +3 3865 3864 3895 +3 3866 3865 3895 +3 3866 3895 3896 +3 3866 3896 3897 +3 3867 3866 3897 +3 3868 3867 3897 +3 3868 3897 3898 +3 3868 3898 3899 +3 3869 3868 3899 +3 3870 3869 3899 +3 3870 3899 3900 +3 3870 3900 3901 +3 3871 3870 3901 +3 3872 3871 3901 +3 3872 3901 3902 +3 3872 3902 3903 +3 3873 3872 3903 +3 3874 3873 3903 +3 3874 3903 3904 +3 3874 3904 3905 +3 3875 3874 3905 +3 3876 3875 3905 +3 3876 3905 3906 +3 3876 3906 3907 +3 3877 3876 3907 +3 3721 3877 3907 +3 3846 3688 3908 +3 3878 3846 3908 +3 3878 3908 3909 +3 3878 3909 3910 +3 3879 3878 3910 +3 3880 3879 3910 +3 3880 3910 3911 +3 3880 3911 3912 +3 3881 3880 3912 +3 3882 3881 3912 +3 3882 3912 3913 +3 3882 3913 3914 +3 3883 3882 3914 +3 3884 3883 3914 +3 3884 3914 3915 +3 3884 3915 3916 +3 3885 3884 3916 +3 3886 3885 3916 +3 3886 3916 3917 +3 3886 3917 3918 +3 3887 3886 3918 +3 3888 3887 3918 +3 3888 3918 3919 +3 3888 3919 3920 +3 3858 3888 3920 +3 3889 3858 3920 +3 3889 3920 3921 +3 3889 3921 3922 +3 3890 3889 3922 +3 3891 3890 3922 +3 3891 3922 3923 +3 3891 3923 3924 +3 3892 3891 3924 +3 3893 3892 3924 +3 3893 3924 3925 +3 3893 3925 3926 +3 3894 3893 3926 +3 3895 3894 3926 +3 3895 3926 3927 +3 3895 3927 3928 +3 3896 3895 3928 +3 3897 3896 3928 +3 3897 3928 3929 +3 3897 3929 3930 +3 3898 3897 3930 +3 3899 3898 3930 +3 3899 3930 3931 +3 3899 3931 3932 +3 3900 3899 3932 +3 3901 3900 3932 +3 3901 3932 3933 +3 3901 3933 3934 +3 3902 3901 3934 +3 3903 3902 3934 +3 3903 3934 3935 +3 3903 3935 3936 +3 3904 3903 3936 +3 3905 3904 3936 +3 3905 3936 3937 +3 3905 3937 3938 +3 3906 3905 3938 +3 3907 3906 3938 +3 3907 3938 3939 +3 3907 3939 3721 +3 3909 3908 3940 +3 3910 3909 3940 +3 3910 3940 3941 +3 3910 3941 3942 +3 3911 3910 3942 +3 3912 3911 3942 +3 3912 3942 3943 +3 3912 3943 3944 +3 3913 3912 3944 +3 3914 3913 3944 +3 3914 3944 3945 +3 3914 3945 3946 +3 3915 3914 3946 +3 3916 3915 3946 +3 3916 3946 3947 +3 3916 3947 3948 +3 3917 3916 3948 +3 3918 3917 3948 +3 3918 3948 3949 +3 3918 3949 3950 +3 3919 3918 3950 +3 3920 3919 3950 +3 3921 3920 3951 +3 3922 3921 3951 +3 3922 3951 3952 +3 3922 3952 3953 +3 3923 3922 3953 +3 3924 3923 3953 +3 3924 3953 3954 +3 3924 3954 3955 +3 3925 3924 3955 +3 3926 3925 3955 +3 3926 3955 3956 +3 3926 3956 3957 +3 3927 3926 3957 +3 3928 3927 3957 +3 3928 3957 3958 +3 3928 3958 3959 +3 3929 3928 3959 +3 3930 3929 3959 +3 3930 3959 3960 +3 3930 3960 3961 +3 3931 3930 3961 +3 3932 3931 3961 +3 3932 3961 3962 +3 3932 3962 3963 +3 3933 3932 3963 +3 3934 3933 3963 +3 3934 3963 3964 +3 3934 3964 3965 +3 3935 3934 3965 +3 3936 3935 3965 +3 3936 3965 3966 +3 3936 3966 3967 +3 3937 3936 3967 +3 3938 3937 3967 +3 3938 3967 3968 +3 3938 3968 3939 +3 3908 3688 3969 +3 3940 3908 3969 +3 3940 3969 3970 +3 3940 3970 3971 +3 3941 3940 3971 +3 3942 3941 3971 +3 3942 3971 3972 +3 3942 3972 3973 +3 3943 3942 3973 +3 3944 3943 3973 +3 3944 3973 3974 +3 3944 3974 3975 +3 3945 3944 3975 +3 3946 3945 3975 +3 3946 3975 3976 +3 3946 3976 3977 +3 3947 3946 3977 +3 3948 3947 3977 +3 3948 3977 3978 +3 3948 3978 3979 +3 3949 3948 3979 +3 3950 3949 3979 +3 3950 3979 3980 +3 3950 3980 3981 +3 3920 3950 3981 +3 3951 3920 3981 +3 3951 3981 3982 +3 3951 3982 3983 +3 3952 3951 3983 +3 3953 3952 3983 +3 3953 3983 3984 +3 3953 3984 3985 +3 3954 3953 3985 +3 3955 3954 3985 +3 3955 3985 3986 +3 3955 3986 3987 +3 3956 3955 3987 +3 3957 3956 3987 +3 3957 3987 3988 +3 3957 3988 3989 +3 3958 3957 3989 +3 3959 3958 3989 +3 3959 3989 3990 +3 3959 3990 3991 +3 3960 3959 3991 +3 3961 3960 3991 +3 3961 3991 3992 +3 3961 3992 3993 +3 3962 3961 3993 +3 3963 3962 3993 +3 3963 3993 3994 +3 3963 3994 3995 +3 3964 3963 3995 +3 3965 3964 3995 +3 3965 3995 3996 +3 3965 3996 3997 +3 3966 3965 3997 +3 3967 3966 3997 +3 3967 3997 3998 +3 3967 3998 3999 +3 3968 3967 3999 +3 3939 3968 3999 +3 3939 3999 4000 +3 3939 4000 3721 +3 3970 3969 4001 +3 3971 3970 4001 +3 3971 4001 4002 +3 3971 4002 4003 +3 3972 3971 4003 +3 3973 3972 4003 +3 3973 4003 4004 +3 3973 4004 4005 +3 3974 3973 4005 +3 3975 3974 4005 +3 3975 4005 4006 +3 3975 4006 4007 +3 3976 3975 4007 +3 3977 3976 4007 +3 3977 4007 4008 +3 3977 4008 4009 +3 3978 3977 4009 +3 3979 3978 4009 +3 3979 4009 4010 +3 3979 4010 4011 +3 3980 3979 4011 +3 3981 3980 4011 +3 3981 4011 4012 +3 3981 4012 4013 +3 3982 3981 4013 +3 3983 3982 4013 +3 3983 4013 4014 +3 3983 4014 4015 +3 3984 3983 4015 +3 3985 3984 4015 +3 3985 4015 4016 +3 3985 4016 4017 +3 3986 3985 4017 +3 3987 3986 4017 +3 3987 4017 4018 +3 3987 4018 4019 +3 3988 3987 4019 +3 3989 3988 4019 +3 3989 4019 4020 +3 3989 4020 4021 +3 3990 3989 4021 +3 3991 3990 4021 +3 3991 4021 4022 +3 3991 4022 4023 +3 3992 3991 4023 +3 3993 3992 4023 +3 3993 4023 4024 +3 3993 4024 4025 +3 3994 3993 4025 +3 3995 3994 4025 +3 3995 4025 4026 +3 3995 4026 4027 +3 3996 3995 4027 +3 3997 3996 4027 +3 3997 4027 4028 +3 3997 4028 4029 +3 3998 3997 4029 +3 3999 3998 4029 +3 3999 4029 4030 +3 3999 4030 4031 +3 4000 3999 4031 +3 3721 4000 4031 +3 3969 3688 4032 +3 4001 3969 4032 +3 4001 4032 4033 +3 4001 4033 4034 +3 4002 4001 4034 +3 4003 4002 4034 +3 4003 4034 4035 +3 4003 4035 4036 +3 4004 4003 4036 +3 4005 4004 4036 +3 4005 4036 4037 +3 4005 4037 4038 +3 4006 4005 4038 +3 4007 4006 4038 +3 4007 4038 4039 +3 4007 4039 4040 +3 4008 4007 4040 +3 4009 4008 4040 +3 4009 4040 4041 +3 4009 4041 4042 +3 4010 4009 4042 +3 4011 4010 4042 +3 4011 4042 4043 +3 4011 4043 4044 +3 4012 4011 4044 +3 4013 4012 4044 +3 4013 4044 4045 +3 4013 4045 4046 +3 4014 4013 4046 +3 4015 4014 4046 +3 4015 4046 4047 +3 4015 4047 4048 +3 4016 4015 4048 +3 4017 4016 4048 +3 4017 4048 4049 +3 4017 4049 4050 +3 4018 4017 4050 +3 4019 4018 4050 +3 4019 4050 4051 +3 4019 4051 4052 +3 4020 4019 4052 +3 4021 4020 4052 +3 4021 4052 4053 +3 4021 4053 4054 +3 4022 4021 4054 +3 4023 4022 4054 +3 4023 4054 4055 +3 4023 4055 4056 +3 4024 4023 4056 +3 4025 4024 4056 +3 4025 4056 4057 +3 4025 4057 4058 +3 4026 4025 4058 +3 4027 4026 4058 +3 4027 4058 4059 +3 4027 4059 4060 +3 4028 4027 4060 +3 4029 4028 4060 +3 4029 4060 4061 +3 4029 4061 4062 +3 4030 4029 4062 +3 4031 4030 4062 +3 4031 4062 4063 +3 4031 4063 3721 +3 4032 3688 4064 +3 4032 4064 4065 +3 4033 4032 4065 +3 4034 4033 4065 +3 4034 4065 4066 +3 4034 4066 4067 +3 4035 4034 4067 +3 4036 4035 4067 +3 4036 4067 4068 +3 4036 4068 4069 +3 4037 4036 4069 +3 4038 4037 4069 +3 4038 4069 4070 +3 4038 4070 4071 +3 4039 4038 4071 +3 4040 4039 4071 +3 4040 4071 4072 +3 4040 4072 4073 +3 4041 4040 4073 +3 4042 4041 4073 +3 4042 4073 4074 +3 4042 4074 4075 +3 4043 4042 4075 +3 4044 4043 4075 +3 4044 4075 4076 +3 4044 4076 4077 +3 4045 4044 4077 +3 4046 4045 4077 +3 4046 4077 4078 +3 4046 4078 4079 +3 4047 4046 4079 +3 4048 4047 4079 +3 4048 4079 4080 +3 4048 4080 4081 +3 4049 4048 4081 +3 4050 4049 4081 +3 4050 4081 4082 +3 4050 4082 4083 +3 4051 4050 4083 +3 4052 4051 4083 +3 4052 4083 4084 +3 4052 4084 4085 +3 4053 4052 4085 +3 4054 4053 4085 +3 4054 4085 4086 +3 4054 4086 4087 +3 4055 4054 4087 +3 4056 4055 4087 +3 4056 4087 4088 +3 4056 4088 4089 +3 4057 4056 4089 +3 4058 4057 4089 +3 4058 4089 4090 +3 4058 4090 4091 +3 4059 4058 4091 +3 4060 4059 4091 +3 4060 4091 4092 +3 4060 4092 4093 +3 4061 4060 4093 +3 4062 4061 4093 +3 4062 4093 4094 +3 4062 4094 4095 +3 4063 4062 4095 +3 3721 4063 4095 +3 4064 3688 4096 +3 4065 4064 4096 +3 4065 4096 4097 +3 4065 4097 4098 +3 4066 4065 4098 +3 4067 4066 4098 +3 4067 4098 4099 +3 4067 4099 4100 +3 4068 4067 4100 +3 4069 4068 4100 +3 4069 4100 4101 +3 4069 4101 4102 +3 4070 4069 4102 +3 4071 4070 4102 +3 4071 4102 4103 +3 4071 4103 4104 +3 4072 4071 4104 +3 4073 4072 4104 +3 4073 4104 4105 +3 4073 4105 4106 +3 4074 4073 4106 +3 4075 4074 4106 +3 4075 4106 4107 +3 4075 4107 4108 +3 4076 4075 4108 +3 4077 4076 4108 +3 4077 4108 4109 +3 4077 4109 4110 +3 4078 4077 4110 +3 4079 4078 4110 +3 4079 4110 4111 +3 4079 4111 4112 +3 4080 4079 4112 +3 4081 4080 4112 +3 4081 4112 4113 +3 4081 4113 4114 +3 4082 4081 4114 +3 4083 4082 4114 +3 4083 4114 4115 +3 4083 4115 4116 +3 4084 4083 4116 +3 4085 4084 4116 +3 4085 4116 4117 +3 4085 4117 4118 +3 4086 4085 4118 +3 4087 4086 4118 +3 4087 4118 4119 +3 4087 4119 4120 +3 4088 4087 4120 +3 4089 4088 4120 +3 4089 4120 4121 +3 4089 4121 4122 +3 4090 4089 4122 +3 4091 4090 4122 +3 4091 4122 4123 +3 4091 4123 4124 +3 4092 4091 4124 +3 4093 4092 4124 +3 4093 4124 4125 +3 4093 4125 4126 +3 4094 4093 4126 +3 4095 4094 4126 +3 4095 4126 4127 +3 4095 4127 3721 +3 4096 3688 4128 +3 4096 4128 4129 +3 4097 4096 4129 +3 4098 4097 4129 +3 4098 4129 4130 +3 4098 4130 4131 +3 4099 4098 4131 +3 4100 4099 4131 +3 4100 4131 4132 +3 4100 4132 4133 +3 4101 4100 4133 +3 4102 4101 4133 +3 4102 4133 4134 +3 4102 4134 4135 +3 4103 4102 4135 +3 4104 4103 4135 +3 4104 4135 4136 +3 4104 4136 4137 +3 4105 4104 4137 +3 4106 4105 4137 +3 4106 4137 4138 +3 4106 4138 4139 +3 4107 4106 4139 +3 4108 4107 4139 +3 4108 4139 4140 +3 4108 4140 4141 +3 4109 4108 4141 +3 4110 4109 4141 +3 4110 4141 4142 +3 4110 4142 4143 +3 4111 4110 4143 +3 4112 4111 4143 +3 4112 4143 4144 +3 4112 4144 4145 +3 4113 4112 4145 +3 4114 4113 4145 +3 4114 4145 4146 +3 4114 4146 4147 +3 4115 4114 4147 +3 4116 4115 4147 +3 4116 4147 4148 +3 4116 4148 4149 +3 4117 4116 4149 +3 4118 4117 4149 +3 4118 4149 4150 +3 4118 4150 4151 +3 4119 4118 4151 +3 4120 4119 4151 +3 4120 4151 4152 +3 4120 4152 4153 +3 4121 4120 4153 +3 4122 4121 4153 +3 4122 4153 4154 +3 4122 4154 4155 +3 4123 4122 4155 +3 4124 4123 4155 +3 4124 4155 4156 +3 4124 4156 4157 +3 4125 4124 4157 +3 4126 4125 4157 +3 4126 4157 4158 +3 4126 4158 4159 +3 4127 4126 4159 +3 3721 4127 4159 +3 4128 3688 4160 +3 4129 4128 4160 +3 4129 4160 4161 +3 4129 4161 4162 +3 4130 4129 4162 +3 4131 4130 4162 +3 4131 4162 4163 +3 4131 4163 4164 +3 4132 4131 4164 +3 4133 4132 4164 +3 4133 4164 4165 +3 4133 4165 4166 +3 4134 4133 4166 +3 4135 4134 4166 +3 4135 4166 4167 +3 4135 4167 4168 +3 4136 4135 4168 +3 4137 4136 4168 +3 4137 4168 4169 +3 4137 4169 4170 +3 4138 4137 4170 +3 4139 4138 4170 +3 4139 4170 4171 +3 4139 4171 4172 +3 4140 4139 4172 +3 4141 4140 4172 +3 4141 4172 4173 +3 4141 4173 4174 +3 4142 4141 4174 +3 4143 4142 4174 +3 4143 4174 4175 +3 4143 4175 4176 +3 4144 4143 4176 +3 4145 4144 4176 +3 4145 4176 4177 +3 4145 4177 4178 +3 4146 4145 4178 +3 4147 4146 4178 +3 4147 4178 4179 +3 4147 4179 4180 +3 4148 4147 4180 +3 4149 4148 4180 +3 4149 4180 4181 +3 4149 4181 4182 +3 4150 4149 4182 +3 4151 4150 4182 +3 4151 4182 4183 +3 4151 4183 4184 +3 4152 4151 4184 +3 4153 4152 4184 +3 4153 4184 4185 +3 4153 4185 4186 +3 4154 4153 4186 +3 4155 4154 4186 +3 4155 4186 4187 +3 4155 4187 4188 +3 4156 4155 4188 +3 4157 4156 4188 +3 4157 4188 4189 +3 4157 4189 4190 +3 4158 4157 4190 +3 4159 4158 4190 +3 4159 4190 4191 +3 4159 4191 3721 +3 4161 4160 4192 +3 4162 4161 4192 +3 4162 4192 4193 +3 4162 4193 4194 +3 4163 4162 4194 +3 4164 4163 4194 +3 4164 4194 4195 +3 4164 4195 4196 +3 4165 4164 4196 +3 4166 4165 4196 +3 4166 4196 4197 +3 4166 4197 4198 +3 4167 4166 4198 +3 4168 4167 4198 +3 4168 4198 4199 +3 4168 4199 4200 +3 4169 4168 4200 +3 4170 4169 4200 +3 4170 4200 4201 +3 4170 4201 4202 +3 4171 4170 4202 +3 4172 4171 4202 +3 4172 4202 4203 +3 4172 4203 4204 +3 4173 4172 4204 +3 4174 4173 4204 +3 4174 4204 4205 +3 4174 4205 4206 +3 4175 4174 4206 +3 4176 4175 4206 +3 4176 4206 4207 +3 4176 4207 4208 +3 4177 4176 4208 +3 4178 4177 4208 +3 4178 4208 4209 +3 4178 4209 4210 +3 4179 4178 4210 +3 4180 4179 4210 +3 4180 4210 4211 +3 4180 4211 4212 +3 4181 4180 4212 +3 4182 4181 4212 +3 4182 4212 4213 +3 4182 4213 4214 +3 4183 4182 4214 +3 4184 4183 4214 +3 4184 4214 4215 +3 4184 4215 4216 +3 4185 4184 4216 +3 4186 4185 4216 +3 4186 4216 4217 +3 4186 4217 4218 +3 4187 4186 4218 +3 4188 4187 4218 +3 4188 4218 4219 +3 4188 4219 4220 +3 4189 4188 4220 +3 4190 4189 4220 +3 4190 4220 4221 +3 4190 4221 4222 +3 4191 4190 4222 +3 3721 4191 4222 +3 4160 3688 4223 +3 4192 4160 4223 +3 4192 4223 4224 +3 4192 4224 4225 +3 4193 4192 4225 +3 4194 4193 4225 +3 4194 4225 4226 +3 4194 4226 4227 +3 4195 4194 4227 +3 4196 4195 4227 +3 4196 4227 4228 +3 4196 4228 4229 +3 4197 4196 4229 +3 4198 4197 4229 +3 4198 4229 4230 +3 4198 4230 4231 +3 4199 4198 4231 +3 4200 4199 4231 +3 4200 4231 4232 +3 4200 4232 4233 +3 4201 4200 4233 +3 4202 4201 4233 +3 4202 4233 4234 +3 4202 4234 4235 +3 4203 4202 4235 +3 4204 4203 4235 +3 4204 4235 4236 +3 4204 4236 4237 +3 4205 4204 4237 +3 4206 4205 4237 +3 4206 4237 4238 +3 4206 4238 4239 +3 4207 4206 4239 +3 4208 4207 4239 +3 4208 4239 4240 +3 4208 4240 4241 +3 4209 4208 4241 +3 4210 4209 4241 +3 4210 4241 4242 +3 4210 4242 4243 +3 4211 4210 4243 +3 4212 4211 4243 +3 4212 4243 4244 +3 4212 4244 4245 +3 4213 4212 4245 +3 4214 4213 4245 +3 4214 4245 4246 +3 4214 4246 4247 +3 4215 4214 4247 +3 4216 4215 4247 +3 4216 4247 4248 +3 4216 4248 4249 +3 4217 4216 4249 +3 4218 4217 4249 +3 4218 4249 4250 +3 4218 4250 4251 +3 4219 4218 4251 +3 4220 4219 4251 +3 4220 4251 4252 +3 4220 4252 4253 +3 4221 4220 4253 +3 4222 4221 4253 +3 4222 4253 4254 +3 4222 4254 3721 +3 4223 3688 4255 +3 4223 4255 4256 +3 4224 4223 4256 +3 4225 4224 4256 +3 4225 4256 4257 +3 4225 4257 4258 +3 4226 4225 4258 +3 4227 4226 4258 +3 4227 4258 4259 +3 4227 4259 4260 +3 4228 4227 4260 +3 4229 4228 4260 +3 4229 4260 4261 +3 4229 4261 4262 +3 4230 4229 4262 +3 4231 4230 4262 +3 4231 4262 4263 +3 4231 4263 4264 +3 4232 4231 4264 +3 4233 4232 4264 +3 4233 4264 4265 +3 4233 4265 4266 +3 4234 4233 4266 +3 4235 4234 4266 +3 4235 4266 4267 +3 4235 4267 4268 +3 4236 4235 4268 +3 4237 4236 4268 +3 4237 4268 4269 +3 4237 4269 4270 +3 4238 4237 4270 +3 4239 4238 4270 +3 4239 4270 4271 +3 4239 4271 4272 +3 4240 4239 4272 +3 4241 4240 4272 +3 4241 4272 4273 +3 4241 4273 4274 +3 4242 4241 4274 +3 4243 4242 4274 +3 4243 4274 4275 +3 4243 4275 4276 +3 4244 4243 4276 +3 4245 4244 4276 +3 4245 4276 4277 +3 4245 4277 4278 +3 4246 4245 4278 +3 4247 4246 4278 +3 4247 4278 4279 +3 4247 4279 4280 +3 4248 4247 4280 +3 4249 4248 4280 +3 4249 4280 4281 +3 4249 4281 4282 +3 4250 4249 4282 +3 4251 4250 4282 +3 4251 4282 4283 +3 4251 4283 4284 +3 4252 4251 4284 +3 4253 4252 4284 +3 4253 4284 4285 +3 4253 4285 4286 +3 4254 4253 4286 +3 3721 4254 4286 +3 4255 3688 4287 +3 4256 4255 4287 +3 4256 4287 4288 +3 4256 4288 4289 +3 4257 4256 4289 +3 4258 4257 4289 +3 4258 4289 4290 +3 4258 4290 4291 +3 4259 4258 4291 +3 4260 4259 4291 +3 4260 4291 4292 +3 4260 4292 4293 +3 4261 4260 4293 +3 4262 4261 4293 +3 4262 4293 4294 +3 4262 4294 4295 +3 4263 4262 4295 +3 4264 4263 4295 +3 4264 4295 4296 +3 4264 4296 4297 +3 4265 4264 4297 +3 4266 4265 4297 +3 4266 4297 4298 +3 4266 4298 4299 +3 4267 4266 4299 +3 4268 4267 4299 +3 4268 4299 4300 +3 4268 4300 4301 +3 4269 4268 4301 +3 4270 4269 4301 +3 4270 4301 4302 +3 4270 4302 4303 +3 4271 4270 4303 +3 4272 4271 4303 +3 4272 4303 4304 +3 4272 4304 4305 +3 4273 4272 4305 +3 4274 4273 4305 +3 4274 4305 4306 +3 4274 4306 4307 +3 4275 4274 4307 +3 4276 4275 4307 +3 4276 4307 4308 +3 4276 4308 4309 +3 4277 4276 4309 +3 4278 4277 4309 +3 4278 4309 4310 +3 4278 4310 4311 +3 4279 4278 4311 +3 4280 4279 4311 +3 4280 4311 4312 +3 4280 4312 4313 +3 4281 4280 4313 +3 4282 4281 4313 +3 4282 4313 4314 +3 4282 4314 4315 +3 4283 4282 4315 +3 4284 4283 4315 +3 4284 4315 4316 +3 4284 4316 4317 +3 4285 4284 4317 +3 4286 4285 4317 +3 4286 4317 4318 +3 4286 4318 3721 +3 4288 4287 4319 +3 4289 4288 4319 +3 4289 4319 4320 +3 4289 4320 4321 +3 4290 4289 4321 +3 4291 4290 4321 +3 4291 4321 4322 +3 4291 4322 4323 +3 4292 4291 4323 +3 4293 4292 4323 +3 4293 4323 4324 +3 4293 4324 4325 +3 4294 4293 4325 +3 4295 4294 4325 +3 4295 4325 4326 +3 4295 4326 4327 +3 4296 4295 4327 +3 4297 4296 4327 +3 4297 4327 4328 +3 4297 4328 4329 +3 4298 4297 4329 +3 4299 4298 4329 +3 4299 4329 4330 +3 4299 4330 4331 +3 4300 4299 4331 +3 4301 4300 4331 +3 4301 4331 4332 +3 4301 4332 4333 +3 4302 4301 4333 +3 4303 4302 4333 +3 4303 4333 4334 +3 4303 4334 4335 +3 4304 4303 4335 +3 4305 4304 4335 +3 4305 4335 4336 +3 4305 4336 4337 +3 4306 4305 4337 +3 4307 4306 4337 +3 4307 4337 4338 +3 4307 4338 4339 +3 4308 4307 4339 +3 4309 4308 4339 +3 4309 4339 4340 +3 4309 4340 4341 +3 4310 4309 4341 +3 4311 4310 4341 +3 4311 4341 4342 +3 4311 4342 4343 +3 4312 4311 4343 +3 4313 4312 4343 +3 4313 4343 4344 +3 4313 4344 4345 +3 4314 4313 4345 +3 4315 4314 4345 +3 4315 4345 4346 +3 4315 4346 4347 +3 4316 4315 4347 +3 4317 4316 4347 +3 4317 4347 4348 +3 4317 4348 4349 +3 4318 4317 4349 +3 3721 4318 4349 +3 4287 3688 4350 +3 4319 4287 4350 +3 4319 4350 4351 +3 4319 4351 4352 +3 4320 4319 4352 +3 4321 4320 4352 +3 4321 4352 4353 +3 4321 4353 4354 +3 4322 4321 4354 +3 4323 4322 4354 +3 4323 4354 4355 +3 4323 4355 4356 +3 4324 4323 4356 +3 4325 4324 4356 +3 4325 4356 4357 +3 4325 4357 4358 +3 4326 4325 4358 +3 4327 4326 4358 +3 4327 4358 4359 +3 4327 4359 4360 +3 4328 4327 4360 +3 4329 4328 4360 +3 4329 4360 4361 +3 4329 4361 4362 +3 4330 4329 4362 +3 4331 4330 4362 +3 4331 4362 4363 +3 4331 4363 4364 +3 4332 4331 4364 +3 4333 4332 4364 +3 4333 4364 4365 +3 4333 4365 4366 +3 4334 4333 4366 +3 4335 4334 4366 +3 4335 4366 4367 +3 4335 4367 4368 +3 4336 4335 4368 +3 4337 4336 4368 +3 4337 4368 4369 +3 4337 4369 4370 +3 4338 4337 4370 +3 4339 4338 4370 +3 4339 4370 4371 +3 4339 4371 4372 +3 4340 4339 4372 +3 4341 4340 4372 +3 4341 4372 4373 +3 4341 4373 4374 +3 4342 4341 4374 +3 4343 4342 4374 +3 4343 4374 4375 +3 4343 4375 4376 +3 4344 4343 4376 +3 4345 4344 4376 +3 4345 4376 4377 +3 4345 4377 4378 +3 4346 4345 4378 +3 4347 4346 4378 +3 4347 4378 4379 +3 4347 4379 4380 +3 4348 4347 4380 +3 4349 4348 4380 +3 4349 4380 4381 +3 4349 4381 3721 +3 4350 3688 4382 +3 4350 4382 4383 +3 4351 4350 4383 +3 4352 4351 4383 +3 4352 4383 4384 +3 4352 4384 4385 +3 4353 4352 4385 +3 4354 4353 4385 +3 4354 4385 4386 +3 4354 4386 4387 +3 4355 4354 4387 +3 4356 4355 4387 +3 4356 4387 4388 +3 4356 4388 4389 +3 4357 4356 4389 +3 4358 4357 4389 +3 4358 4389 4390 +3 4358 4390 4391 +3 4359 4358 4391 +3 4360 4359 4391 +3 4360 4391 4392 +3 4360 4392 4393 +3 4361 4360 4393 +3 4362 4361 4393 +3 4362 4393 4394 +3 4362 4394 4395 +3 4363 4362 4395 +3 4364 4363 4395 +3 4364 4395 4396 +3 4364 4396 4397 +3 4365 4364 4397 +3 4366 4365 4397 +3 4366 4397 4398 +3 4366 4398 4399 +3 4367 4366 4399 +3 4368 4367 4399 +3 4368 4399 4400 +3 4368 4400 4401 +3 4369 4368 4401 +3 4370 4369 4401 +3 4370 4401 4402 +3 4370 4402 4403 +3 4371 4370 4403 +3 4372 4371 4403 +3 4372 4403 4404 +3 4372 4404 4405 +3 4373 4372 4405 +3 4374 4373 4405 +3 4374 4405 4406 +3 4374 4406 4407 +3 4375 4374 4407 +3 4376 4375 4407 +3 4376 4407 4408 +3 4376 4408 4409 +3 4377 4376 4409 +3 4378 4377 4409 +3 4378 4409 4410 +3 4378 4410 4411 +3 4379 4378 4411 +3 4380 4379 4411 +3 4380 4411 4412 +3 4380 4412 4413 +3 4381 4380 4413 +3 3721 4381 4413 +3 4382 3688 4414 +3 4383 4382 4414 +3 4383 4414 4415 +3 4383 4415 4416 +3 4384 4383 4416 +3 4385 4384 4416 +3 4385 4416 4417 +3 4385 4417 4418 +3 4386 4385 4418 +3 4387 4386 4418 +3 4387 4418 4419 +3 4387 4419 4420 +3 4388 4387 4420 +3 4389 4388 4420 +3 4389 4420 4421 +3 4389 4421 4422 +3 4390 4389 4422 +3 4391 4390 4422 +3 4391 4422 4423 +3 4391 4423 4424 +3 4392 4391 4424 +3 4393 4392 4424 +3 4393 4424 4425 +3 4393 4425 4426 +3 4394 4393 4426 +3 4395 4394 4426 +3 4395 4426 4427 +3 4395 4427 4428 +3 4396 4395 4428 +3 4397 4396 4428 +3 4397 4428 4429 +3 4397 4429 4430 +3 4398 4397 4430 +3 4399 4398 4430 +3 4399 4430 4431 +3 4399 4431 4432 +3 4400 4399 4432 +3 4401 4400 4432 +3 4401 4432 4433 +3 4401 4433 4434 +3 4402 4401 4434 +3 4403 4402 4434 +3 4403 4434 4435 +3 4403 4435 4436 +3 4404 4403 4436 +3 4405 4404 4436 +3 4405 4436 4437 +3 4405 4437 4438 +3 4406 4405 4438 +3 4407 4406 4438 +3 4407 4438 4439 +3 4407 4439 4440 +3 4408 4407 4440 +3 4409 4408 4440 +3 4409 4440 4441 +3 4409 4441 4442 +3 4410 4409 4442 +3 4411 4410 4442 +3 4411 4442 4443 +3 4411 4443 4444 +3 4412 4411 4444 +3 4413 4412 4444 +3 4413 4444 4445 +3 4413 4445 3721 +3 4414 3688 4446 +3 4414 4446 4447 +3 4415 4414 4447 +3 4416 4415 4447 +3 4416 4447 4448 +3 4416 4448 4449 +3 4417 4416 4449 +3 4418 4417 4449 +3 4418 4449 4450 +3 4418 4450 4451 +3 4419 4418 4451 +3 4420 4419 4451 +3 4420 4451 4452 +3 4420 4452 4453 +3 4421 4420 4453 +3 4422 4421 4453 +3 4422 4453 4454 +3 4422 4454 4455 +3 4423 4422 4455 +3 4424 4423 4455 +3 4424 4455 4456 +3 4424 4456 4457 +3 4425 4424 4457 +3 4426 4425 4457 +3 4426 4457 4458 +3 4426 4458 4459 +3 4427 4426 4459 +3 4428 4427 4459 +3 4428 4459 4460 +3 4428 4460 4461 +3 4429 4428 4461 +3 4430 4429 4461 +3 4430 4461 4462 +3 4430 4462 4463 +3 4431 4430 4463 +3 4432 4431 4463 +3 4432 4463 4464 +3 4432 4464 4465 +3 4433 4432 4465 +3 4434 4433 4465 +3 4434 4465 4466 +3 4434 4466 4467 +3 4435 4434 4467 +3 4436 4435 4467 +3 4436 4467 4468 +3 4436 4468 4469 +3 4437 4436 4469 +3 4438 4437 4469 +3 4438 4469 4470 +3 4438 4470 4471 +3 4439 4438 4471 +3 4440 4439 4471 +3 4440 4471 4472 +3 4440 4472 4473 +3 4441 4440 4473 +3 4442 4441 4473 +3 4442 4473 4474 +3 4442 4474 4475 +3 4443 4442 4475 +3 4444 4443 4475 +3 4444 4475 4476 +3 4444 4476 4477 +3 4445 4444 4477 +3 3721 4445 4477 +3 4447 4446 4478 +3 4447 4478 4479 +3 4448 4447 4479 +3 4449 4448 4479 +3 4449 4479 4480 +3 4449 4480 4481 +3 4450 4449 4481 +3 4451 4450 4481 +3 4451 4481 4482 +3 4451 4482 4483 +3 4452 4451 4483 +3 4453 4452 4483 +3 4453 4483 4484 +3 4453 4484 4485 +3 4454 4453 4485 +3 4455 4454 4485 +3 4455 4485 4486 +3 4455 4486 4487 +3 4456 4455 4487 +3 4457 4456 4487 +3 4457 4487 4488 +3 4457 4488 4489 +3 4458 4457 4489 +3 4459 4458 4489 +3 4459 4489 4490 +3 4459 4490 4491 +3 4460 4459 4491 +3 4461 4460 4491 +3 4461 4491 4492 +3 4461 4492 4493 +3 4462 4461 4493 +3 4463 4462 4493 +3 4463 4493 4494 +3 4463 4494 4495 +3 4464 4463 4495 +3 4465 4464 4495 +3 4465 4495 4496 +3 4465 4496 4497 +3 4466 4465 4497 +3 4467 4466 4497 +3 4467 4497 4498 +3 4467 4498 4499 +3 4468 4467 4499 +3 4469 4468 4499 +3 4469 4499 4500 +3 4469 4500 4501 +3 4470 4469 4501 +3 4471 4470 4501 +3 4471 4501 4502 +3 4471 4502 4503 +3 4472 4471 4503 +3 4473 4472 4503 +3 4473 4503 4504 +3 4473 4504 4505 +3 4474 4473 4505 +3 4475 4474 4505 +3 4475 4505 4506 +3 4475 4506 4507 +3 4476 4475 4507 +3 4477 4476 4507 +3 4477 4507 4508 +3 4477 4508 3721 +3 4446 3688 3628 +3 4446 3628 3627 +3 4478 4446 3627 +3 4479 4478 3627 +3 4479 3627 3631 +3 4479 3631 3632 +3 4480 4479 3632 +3 4481 4480 3632 +3 4481 3632 3635 +3 4481 3635 3636 +3 4482 4481 3636 +3 4483 4482 3636 +3 4483 3636 3639 +3 4483 3639 3640 +3 4484 4483 3640 +3 4485 4484 3640 +3 4485 3640 3643 +3 4485 3643 3644 +3 4486 4485 3644 +3 4487 4486 3644 +3 4487 3644 3647 +3 4487 3647 3648 +3 4488 4487 3648 +3 4489 4488 3648 +3 4489 3648 3650 +3 4489 3650 3651 +3 4490 4489 3651 +3 4491 4490 3651 +3 4491 3651 3654 +3 4491 3654 3655 +3 4492 4491 3655 +3 4493 4492 3655 +3 4493 3655 3658 +3 4493 3658 3659 +3 4494 4493 3659 +3 4495 4494 3659 +3 4495 3659 3662 +3 4495 3662 3663 +3 4496 4495 3663 +3 4497 4496 3663 +3 4497 3663 3666 +3 4497 3666 3667 +3 4498 4497 3667 +3 4499 4498 3667 +3 4499 3667 3670 +3 4499 3670 3671 +3 4500 4499 3671 +3 4501 4500 3671 +3 4501 3671 3674 +3 4501 3674 3675 +3 4502 4501 3675 +3 4503 4502 3675 +3 4503 3675 3678 +3 4503 3678 3679 +3 4504 4503 3679 +3 4505 4504 3679 +3 4505 3679 3682 +3 4505 3682 3683 +3 4506 4505 3683 +3 4507 4506 3683 +3 4507 3683 3686 +3 4507 3686 3687 +3 4508 4507 3687 +3 3721 4508 3687 +3 4509 4510 4511 +3 4509 4511 4512 +3 4513 4509 4512 +3 4514 4513 4512 +3 4514 4512 4515 +3 4514 4515 4516 +3 4517 4514 4516 +3 4518 4517 4516 +3 4518 4516 4519 +3 4518 4519 4520 +3 4521 4518 4520 +3 4522 4521 4520 +3 4522 4520 4523 +3 4522 4523 4524 +3 4525 4522 4524 +3 4526 4525 4524 +3 4526 4524 4527 +3 4526 4527 4528 +3 4529 4526 4528 +3 4530 4529 4528 +3 4530 4528 4531 +3 4530 4531 4532 +3 4533 4530 4532 +3 4534 4533 4532 +3 4534 4532 4535 +3 4534 4535 4536 +3 4537 4534 4536 +3 4538 4537 4536 +3 4538 4536 4539 +3 4538 4539 4540 +3 4541 4538 4540 +3 4542 4541 4540 +3 4542 4540 4543 +3 4542 4543 4544 +3 4545 4544 4546 +3 4545 4546 4547 +3 4548 4545 4547 +3 4549 4548 4547 +3 4549 4547 4550 +3 4549 4550 4551 +3 4511 4510 4552 +3 4512 4511 4552 +3 4512 4552 4553 +3 4512 4553 4554 +3 4515 4512 4554 +3 4516 4515 4554 +3 4516 4554 4555 +3 4516 4555 4556 +3 4519 4516 4556 +3 4520 4519 4556 +3 4520 4556 4557 +3 4520 4557 4558 +3 4523 4520 4558 +3 4524 4523 4558 +3 4524 4558 4559 +3 4524 4559 4560 +3 4527 4524 4560 +3 4528 4527 4560 +3 4528 4560 4561 +3 4528 4561 4562 +3 4531 4528 4562 +3 4532 4531 4562 +3 4532 4562 4563 +3 4532 4563 4564 +3 4535 4532 4564 +3 4536 4535 4564 +3 4536 4564 4565 +3 4536 4565 4566 +3 4539 4536 4566 +3 4540 4539 4566 +3 4540 4566 4567 +3 4540 4567 4568 +3 4543 4540 4568 +3 4544 4543 4568 +3 4544 4568 4569 +3 4544 4569 4546 +3 4547 4546 4570 +3 4547 4570 4571 +3 4550 4547 4571 +3 4551 4550 4571 +3 4552 4510 4572 +3 4552 4572 4573 +3 4553 4552 4573 +3 4554 4553 4573 +3 4554 4573 4574 +3 4554 4574 4575 +3 4555 4554 4575 +3 4556 4555 4575 +3 4556 4575 4576 +3 4556 4576 4577 +3 4557 4556 4577 +3 4558 4557 4577 +3 4558 4577 4578 +3 4558 4578 4579 +3 4559 4558 4579 +3 4560 4559 4579 +3 4560 4579 4580 +3 4560 4580 4581 +3 4561 4560 4581 +3 4562 4561 4581 +3 4562 4581 4582 +3 4562 4582 4583 +3 4563 4562 4583 +3 4564 4563 4583 +3 4564 4583 4584 +3 4564 4584 4565 +3 4566 4565 4585 +3 4566 4585 4586 +3 4567 4566 4586 +3 4568 4567 4586 +3 4568 4586 4587 +3 4568 4587 4569 +3 4546 4569 4588 +3 4546 4588 4589 +3 4570 4546 4589 +3 4571 4570 4589 +3 4571 4589 4590 +3 4571 4590 4551 +3 4572 4510 4591 +3 4573 4572 4591 +3 4573 4591 4592 +3 4573 4592 4593 +3 4574 4573 4593 +3 4575 4574 4593 +3 4575 4593 4594 +3 4575 4594 4595 +3 4576 4575 4595 +3 4577 4576 4595 +3 4577 4595 4596 +3 4577 4596 4597 +3 4578 4577 4597 +3 4579 4578 4597 +3 4579 4597 4598 +3 4579 4598 4599 +3 4580 4579 4599 +3 4581 4580 4599 +3 4581 4599 4600 +3 4581 4600 4601 +3 4582 4581 4601 +3 4583 4582 4601 +3 4583 4601 4602 +3 4583 4602 4603 +3 4584 4583 4603 +3 4565 4584 4603 +3 4565 4603 4604 +3 4565 4604 4605 +3 4585 4565 4605 +3 4586 4585 4605 +3 4586 4605 4606 +3 4586 4606 4607 +3 4587 4586 4607 +3 4569 4587 4607 +3 4569 4607 4608 +3 4569 4608 4609 +3 4588 4569 4609 +3 4589 4588 4609 +3 4589 4609 4610 +3 4589 4610 4611 +3 4590 4589 4611 +3 4551 4590 4611 +3 4591 4510 4612 +3 4591 4612 4613 +3 4592 4591 4613 +3 4593 4592 4613 +3 4593 4613 4614 +3 4593 4614 4615 +3 4594 4593 4615 +3 4595 4594 4615 +3 4595 4615 4616 +3 4595 4616 4617 +3 4596 4595 4617 +3 4597 4596 4617 +3 4597 4617 4618 +3 4597 4618 4619 +3 4598 4597 4619 +3 4599 4598 4619 +3 4599 4619 4620 +3 4599 4620 4621 +3 4600 4599 4621 +3 4601 4600 4621 +3 4601 4621 4622 +3 4601 4622 4623 +3 4602 4601 4623 +3 4603 4602 4623 +3 4603 4623 4624 +3 4603 4624 4625 +3 4604 4603 4625 +3 4605 4604 4625 +3 4605 4625 4626 +3 4605 4626 4627 +3 4606 4605 4627 +3 4607 4606 4627 +3 4607 4627 4628 +3 4607 4628 4608 +3 4609 4608 4629 +3 4609 4629 4630 +3 4610 4609 4630 +3 4611 4610 4630 +3 4611 4630 4631 +3 4611 4631 4551 +3 4612 4510 4632 +3 4613 4612 4632 +3 4613 4632 4633 +3 4613 4633 4634 +3 4614 4613 4634 +3 4615 4614 4634 +3 4615 4634 4635 +3 4615 4635 4636 +3 4616 4615 4636 +3 4617 4616 4636 +3 4617 4636 4637 +3 4617 4637 4638 +3 4618 4617 4638 +3 4619 4618 4638 +3 4619 4638 4639 +3 4619 4639 4640 +3 4620 4619 4640 +3 4621 4620 4640 +3 4621 4640 4641 +3 4621 4641 4642 +3 4622 4621 4642 +3 4623 4622 4642 +3 4623 4642 4643 +3 4623 4643 4644 +3 4624 4623 4644 +3 4625 4624 4644 +3 4625 4644 4645 +3 4625 4645 4646 +3 4626 4625 4646 +3 4627 4626 4646 +3 4627 4646 4647 +3 4627 4647 4648 +3 4628 4627 4648 +3 4608 4628 4648 +3 4608 4648 4544 +3 4608 4544 4629 +3 4630 4629 4649 +3 4630 4649 4650 +3 4631 4630 4650 +3 4551 4631 4650 +3 4632 4510 4651 +3 4632 4651 4652 +3 4633 4632 4652 +3 4634 4633 4652 +3 4634 4652 4653 +3 4634 4653 4654 +3 4635 4634 4654 +3 4636 4635 4654 +3 4636 4654 4655 +3 4636 4655 4656 +3 4637 4636 4656 +3 4638 4637 4656 +3 4638 4656 4657 +3 4638 4657 4658 +3 4639 4638 4658 +3 4640 4639 4658 +3 4640 4658 4659 +3 4640 4659 4660 +3 4641 4640 4660 +3 4642 4641 4660 +3 4642 4660 4661 +3 4642 4661 4662 +3 4643 4642 4662 +3 4644 4643 4662 +3 4644 4662 4663 +3 4644 4663 4645 +3 4646 4645 4664 +3 4646 4664 4665 +3 4647 4646 4665 +3 4648 4647 4665 +3 4648 4665 4666 +3 4648 4666 4544 +3 4629 4544 4667 +3 4629 4667 4668 +3 4649 4629 4668 +3 4650 4649 4668 +3 4650 4668 4669 +3 4650 4669 4551 +3 4651 4510 4509 +3 4652 4651 4509 +3 4652 4509 4513 +3 4652 4513 4514 +3 4653 4652 4514 +3 4654 4653 4514 +3 4654 4514 4517 +3 4654 4517 4518 +3 4655 4654 4518 +3 4656 4655 4518 +3 4656 4518 4521 +3 4656 4521 4522 +3 4657 4656 4522 +3 4658 4657 4522 +3 4658 4522 4525 +3 4658 4525 4526 +3 4659 4658 4526 +3 4660 4659 4526 +3 4660 4526 4529 +3 4660 4529 4530 +3 4661 4660 4530 +3 4662 4661 4530 +3 4662 4530 4533 +3 4662 4533 4534 +3 4663 4662 4534 +3 4645 4663 4534 +3 4645 4534 4537 +3 4645 4537 4538 +3 4664 4645 4538 +3 4665 4664 4538 +3 4665 4538 4541 +3 4665 4541 4542 +3 4666 4665 4542 +3 4544 4666 4542 +3 4667 4544 4545 +3 4668 4667 4545 +3 4668 4545 4548 +3 4668 4548 4549 +3 4669 4668 4549 +3 4551 4669 4549 diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/stl/space_invader_magnet.stl b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/stl/space_invader_magnet.stl new file mode 100644 index 0000000..479dce2 --- /dev/null +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/models/stl/space_invader_magnet.stl @@ -0,0 +1,2634 @@ +solid Default + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 5.456000e+00 + vertex -7.086578e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -7.086578e+00 2.362057e+00 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 5.456000e+00 + vertex -7.086578e+00 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 7.086580e+00 2.362057e+00 3.472000e+00 + vertex 7.086580e+00 2.362057e+00 5.456000e+00 + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + vertex 7.086580e+00 2.362057e+00 5.456000e+00 + vertex 7.086580e+00 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 2.362195e+00 -1.653549e+01 5.456000e+00 + vertex 2.362195e+00 -2.125987e+01 5.456000e+00 + vertex 1.181097e+01 -1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 -1.653549e+01 5.456000e+00 + vertex 2.362195e+00 -2.125987e+01 5.456000e+00 + vertex 1.653535e+01 -2.125987e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 -1.653549e+01 5.456000e+00 + vertex 1.653535e+01 -2.125987e+01 5.456000e+00 + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 1.653535e+01 -2.125987e+01 5.456000e+00 + vertex 1.653535e+01 -1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -7.086578e+00 -2.362329e+00 5.456000e+00 + vertex 7.086580e+00 -2.362329e+00 5.456000e+00 + vertex -7.086578e+00 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -7.086578e+00 2.362057e+00 5.456000e+00 + vertex 7.086580e+00 -2.362329e+00 5.456000e+00 + vertex 7.086580e+00 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 5.456000e+00 + vertex 1.181097e+01 7.086444e+00 5.456000e+00 + vertex 7.086580e+00 1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 7.086580e+00 1.653549e+01 5.456000e+00 + vertex 1.181097e+01 7.086444e+00 5.456000e+00 + vertex 1.181097e+01 1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 7.086580e+00 1.653549e+01 5.456000e+00 + vertex 1.181097e+01 1.181110e+01 5.456000e+00 + vertex 1.417316e+01 1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.417316e+01 1.653549e+01 5.456000e+00 + vertex 1.181097e+01 1.181110e+01 5.456000e+00 + vertex 1.653535e+01 1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.417316e+01 1.653549e+01 5.456000e+00 + vertex 1.653535e+01 1.181110e+01 5.456000e+00 + vertex 1.417316e+01 2.125987e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.417316e+01 2.125987e+01 5.456000e+00 + vertex 1.653535e+01 1.181110e+01 5.456000e+00 + vertex 1.653535e+01 1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.417316e+01 2.125987e+01 5.456000e+00 + vertex 1.653535e+01 1.653549e+01 5.456000e+00 + vertex 2.125974e+01 2.125987e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 2.125974e+01 2.125987e+01 5.456000e+00 + vertex 1.653535e+01 1.653549e+01 5.456000e+00 + vertex 2.125974e+01 1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 2.598412e+01 2.362057e+00 5.456000e+00 + vertex 2.125974e+01 2.362057e+00 5.456000e+00 + vertex 2.598412e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 2.598412e+01 -2.362329e+00 5.456000e+00 + vertex 2.125974e+01 2.362057e+00 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 2.598412e+01 -2.362329e+00 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + vertex 3.070851e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 3.070851e+01 -2.362329e+00 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + vertex 2.598412e+01 -7.086715e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 3.070851e+01 -2.362329e+00 5.456000e+00 + vertex 2.598412e+01 -7.086715e+00 5.456000e+00 + vertex 3.070851e+01 -1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 3.070851e+01 -1.653549e+01 5.456000e+00 + vertex 2.598412e+01 -7.086715e+00 5.456000e+00 + vertex 2.598412e+01 -1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.653535e+01 -1.653549e+01 5.456000e+00 + vertex 2.125974e+01 -1.653549e+01 5.456000e+00 + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 2.125974e+01 -1.653549e+01 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + vertex 1.181097e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 -2.362329e+00 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + vertex 2.125974e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 -2.362329e+00 5.456000e+00 + vertex 2.125974e+01 2.362057e+00 5.456000e+00 + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + vertex 2.125974e+01 2.362057e+00 5.456000e+00 + vertex 2.125974e+01 7.086444e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 2.125974e+01 7.086444e+00 5.456000e+00 + vertex 1.181097e+01 7.086444e+00 5.456000e+00 + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + vertex 1.181097e+01 7.086444e+00 5.456000e+00 + vertex 7.086580e+00 7.086444e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + vertex 7.086580e+00 7.086444e+00 5.456000e+00 + vertex 7.086580e+00 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 7.086580e+00 2.362057e+00 5.456000e+00 + vertex 7.086580e+00 7.086444e+00 5.456000e+00 + vertex -7.086578e+00 7.086444e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 7.086580e+00 2.362057e+00 5.456000e+00 + vertex -7.086578e+00 7.086444e+00 5.456000e+00 + vertex -7.086578e+00 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.653535e+01 1.653549e+01 5.456000e+00 + vertex -1.653535e+01 1.181110e+01 5.456000e+00 + vertex -1.181097e+01 1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -2.125974e+01 2.125987e+01 5.456000e+00 + vertex -2.125974e+01 1.653549e+01 5.456000e+00 + vertex -1.417316e+01 2.125987e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.417316e+01 2.125987e+01 5.456000e+00 + vertex -2.125974e+01 1.653549e+01 5.456000e+00 + vertex -1.653535e+01 1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.417316e+01 2.125987e+01 5.456000e+00 + vertex -1.653535e+01 1.653549e+01 5.456000e+00 + vertex -1.417316e+01 1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.417316e+01 1.653549e+01 5.456000e+00 + vertex -1.653535e+01 1.653549e+01 5.456000e+00 + vertex -1.181097e+01 1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.417316e+01 1.653549e+01 5.456000e+00 + vertex -1.181097e+01 1.181110e+01 5.456000e+00 + vertex -7.086578e+00 1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -7.086578e+00 1.653549e+01 5.456000e+00 + vertex -1.181097e+01 1.181110e+01 5.456000e+00 + vertex -1.181097e+01 7.086444e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -7.086578e+00 1.653549e+01 5.456000e+00 + vertex -1.181097e+01 7.086444e+00 5.456000e+00 + vertex -7.086578e+00 7.086444e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -7.086578e+00 7.086444e+00 5.456000e+00 + vertex -1.181097e+01 7.086444e+00 5.456000e+00 + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -7.086578e+00 7.086444e+00 5.456000e+00 + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + vertex -7.086578e+00 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.653535e+01 -1.653549e+01 5.456000e+00 + vertex -1.653535e+01 -2.125987e+01 5.456000e+00 + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + vertex -1.653535e+01 -2.125987e+01 5.456000e+00 + vertex -2.362193e+00 -2.125987e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + vertex -2.362193e+00 -2.125987e+01 5.456000e+00 + vertex -2.362193e+00 -1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -3.070851e+01 -1.653549e+01 5.456000e+00 + vertex -2.598412e+01 -1.653549e+01 5.456000e+00 + vertex -3.070851e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -3.070851e+01 -2.362329e+00 5.456000e+00 + vertex -2.598412e+01 -1.653549e+01 5.456000e+00 + vertex -2.598412e+01 -7.086715e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -3.070851e+01 -2.362329e+00 5.456000e+00 + vertex -2.598412e+01 -7.086715e+00 5.456000e+00 + vertex -2.598412e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -2.598412e+01 -2.362329e+00 5.456000e+00 + vertex -2.598412e+01 -7.086715e+00 5.456000e+00 + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -2.598412e+01 -2.362329e+00 5.456000e+00 + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + vertex -2.598412e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -2.598412e+01 2.362057e+00 5.456000e+00 + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -2.125974e+01 -1.653549e+01 5.456000e+00 + vertex -1.653535e+01 -1.653549e+01 5.456000e+00 + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + vertex -1.653535e+01 -1.653549e+01 5.456000e+00 + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + vertex -1.181097e+01 -1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.181097e+01 7.086444e+00 5.456000e+00 + vertex -2.125974e+01 7.086444e+00 5.456000e+00 + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + vertex -2.125974e+01 7.086444e+00 5.456000e+00 + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + vertex -1.181097e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.181097e+01 -2.362329e+00 5.456000e+00 + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + vertex -1.181097e+01 -1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -1.181097e+01 -2.362329e+00 5.456000e+00 + vertex -1.181097e+01 -1.181110e+01 5.456000e+00 + vertex -7.086578e+00 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -7.086578e+00 -2.362329e+00 5.456000e+00 + vertex -1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex -7.086578e+00 -2.362329e+00 5.456000e+00 + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 7.086580e+00 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 6.123234e-17 1.000000e+00 + outer loop + vertex 7.086580e+00 -2.362329e+00 5.456000e+00 + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 1.181097e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.866333e+00 2.362057e+00 1.157158e-15 + vertex 6.943716e+00 3.636320e+00 1.079131e-15 + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 6.943716e+00 3.636320e+00 1.079131e-15 + vertex 5.816999e+00 4.734257e+00 1.011902e-15 + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + vertex 5.816999e+00 4.734257e+00 1.011902e-15 + vertex 4.519291e+00 5.623595e+00 9.574459e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + vertex 4.519291e+00 5.623595e+00 9.574459e-16 + vertex 3.088746e+00 6.278193e+00 9.173633e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.653535e+01 1.653549e+01 2.892853e-16 + vertex 1.653535e+01 1.181110e+01 5.785704e-16 + vertex 1.181097e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 9.050850e+00 -3.872648e+00 1.538923e-15 + vertex 9.176000e+00 -2.362329e+00 1.446443e-15 + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.362193e+00 -1.653549e+01 2.314298e-15 + vertex -2.362193e+00 -2.125987e+01 2.603584e-15 + vertex -1.181097e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 -1.653549e+01 2.314298e-15 + vertex -2.362193e+00 -2.125987e+01 2.603584e-15 + vertex -1.653535e+01 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 -1.653549e+01 2.314298e-15 + vertex -1.653535e+01 -2.125987e+01 2.603584e-15 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 7.086444e+00 8.678722e-16 + vertex 2.125974e+01 7.086444e+00 8.678722e-16 + vertex 2.125974e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 2.125974e+01 2.125987e+01 0.000000e+00 + vertex 2.125974e+01 1.653549e+01 2.892853e-16 + vertex 1.417316e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.417316e+01 2.125987e+01 0.000000e+00 + vertex 2.125974e+01 1.653549e+01 2.892853e-16 + vertex 1.653535e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.417316e+01 2.125987e+01 0.000000e+00 + vertex 1.653535e+01 1.653549e+01 2.892853e-16 + vertex 1.417316e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.417316e+01 1.653549e+01 2.892853e-16 + vertex 1.653535e+01 1.653549e+01 2.892853e-16 + vertex 1.181097e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.417316e+01 1.653549e+01 2.892853e-16 + vertex 1.181097e+01 1.181110e+01 5.785704e-16 + vertex 7.086580e+00 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 1.653549e+01 2.892853e-16 + vertex 1.181097e+01 1.181110e+01 5.785704e-16 + vertex 1.181097e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 1.653549e+01 2.892853e-16 + vertex 1.181097e+01 7.086444e+00 8.678722e-16 + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + vertex 1.181097e+01 7.086444e+00 8.678722e-16 + vertex 1.181097e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + vertex 1.181097e+01 2.362057e+00 1.157158e-15 + vertex 7.866333e+00 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 7.086444e+00 8.678722e-16 + vertex 2.125974e+01 2.362057e+00 1.157158e-15 + vertex 1.181097e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 2.362057e+00 1.157158e-15 + vertex 2.125974e+01 2.362057e+00 1.157158e-15 + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 2.362057e+00 1.157158e-15 + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + vertex 2.125974e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + vertex 2.125974e+01 -1.653549e+01 2.314298e-15 + vertex 1.653535e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 3.070851e+01 -1.653549e+01 2.314298e-15 + vertex 2.598412e+01 -1.653549e+01 2.314298e-15 + vertex 3.070851e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 3.070851e+01 -2.362329e+00 1.446443e-15 + vertex 2.598412e+01 -1.653549e+01 2.314298e-15 + vertex 2.598412e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 3.070851e+01 -2.362329e+00 1.446443e-15 + vertex 2.598412e+01 -7.086715e+00 1.735728e-15 + vertex 2.598412e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 2.598412e+01 -2.362329e+00 1.446443e-15 + vertex 2.598412e+01 -7.086715e+00 1.735728e-15 + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 2.598412e+01 -2.362329e+00 1.446443e-15 + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + vertex 2.598412e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 2.598412e+01 2.362057e+00 1.157158e-15 + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + vertex 2.125974e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.653535e+01 -2.125987e+01 2.603584e-15 + vertex -1.653535e+01 -1.653549e+01 2.314298e-15 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -1.653535e+01 -1.653549e+01 2.314298e-15 + vertex -2.125974e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -2.125974e+01 -1.653549e+01 2.314298e-15 + vertex -2.125974e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + vertex -1.181097e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 2.362057e+00 1.157158e-15 + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + vertex -2.125974e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 2.362057e+00 1.157158e-15 + vertex -2.125974e+01 7.086444e+00 8.678722e-16 + vertex -7.866329e+00 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + vertex -1.181097e+01 7.086444e+00 8.678722e-16 + vertex -1.181097e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 3.088746e+00 6.278193e+00 9.173633e-16 + vertex 1.567411e+00 6.678811e+00 8.928326e-16 + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + vertex 1.567411e+00 6.678811e+00 8.928326e-16 + vertex 0.000000e+00 6.813671e+00 8.845748e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + vertex 0.000000e+00 6.813671e+00 8.845748e-16 + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + vertex 0.000000e+00 6.813671e+00 8.845748e-16 + vertex -1.567409e+00 6.678811e+00 8.928326e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex 8.070051e+00 -6.729622e+00 1.713862e-15 + vertex 8.678819e+00 -5.341771e+00 1.628881e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.125974e+01 1.653549e+01 2.892853e-16 + vertex -2.125974e+01 2.125987e+01 0.000000e+00 + vertex -1.653535e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.653535e+01 1.653549e+01 2.892853e-16 + vertex -2.125974e+01 2.125987e+01 0.000000e+00 + vertex -1.417316e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.653535e+01 1.653549e+01 2.892853e-16 + vertex -1.417316e+01 2.125987e+01 0.000000e+00 + vertex -1.653535e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.653535e+01 1.181110e+01 5.785704e-16 + vertex -1.417316e+01 2.125987e+01 0.000000e+00 + vertex -1.417316e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.653535e+01 1.181110e+01 5.785704e-16 + vertex -1.417316e+01 1.653549e+01 2.892853e-16 + vertex -1.181097e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 1.181110e+01 5.785704e-16 + vertex -1.417316e+01 1.653549e+01 2.892853e-16 + vertex -7.086578e+00 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 1.181110e+01 5.785704e-16 + vertex -7.086578e+00 1.653549e+01 2.892853e-16 + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.598412e+01 -1.653549e+01 2.314298e-15 + vertex -3.070851e+01 -1.653549e+01 2.314298e-15 + vertex -2.598412e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.598412e+01 -7.086715e+00 1.735728e-15 + vertex -3.070851e+01 -1.653549e+01 2.314298e-15 + vertex -3.070851e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.598412e+01 -7.086715e+00 1.735728e-15 + vertex -3.070851e+01 -2.362329e+00 1.446443e-15 + vertex -2.125974e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.125974e+01 -7.086715e+00 1.735728e-15 + vertex -3.070851e+01 -2.362329e+00 1.446443e-15 + vertex -2.598412e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.125974e+01 -7.086715e+00 1.735728e-15 + vertex -2.598412e+01 -2.362329e+00 1.446443e-15 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -5.018795e+00 -1.004417e+01 1.916820e-15 + vertex -3.685958e+00 -1.076547e+01 1.960986e-15 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 2.362195e+00 -2.125987e+01 2.603584e-15 + vertex 2.362195e+00 -1.653549e+01 2.314298e-15 + vertex 1.653535e+01 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.653535e+01 -2.125987e+01 2.603584e-15 + vertex 2.362195e+00 -1.653549e+01 2.314298e-15 + vertex 1.181097e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.653535e+01 -2.125987e+01 2.603584e-15 + vertex 1.181097e+01 -1.653549e+01 2.314298e-15 + vertex 1.653535e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.653535e+01 -1.653549e+01 2.314298e-15 + vertex 1.181097e+01 -1.653549e+01 2.314298e-15 + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.653535e+01 -1.653549e+01 2.314298e-15 + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex 8.678819e+00 -5.341771e+00 1.628881e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + vertex 8.678819e+00 -5.341771e+00 1.628881e-15 + vertex 9.050850e+00 -3.872648e+00 1.538923e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -9.176000e+00 -2.362329e+00 1.446443e-15 + vertex -9.050850e+00 -3.872648e+00 1.538923e-15 + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + vertex -9.050850e+00 -3.872648e+00 1.538923e-15 + vertex -8.678817e+00 -5.341771e+00 1.628881e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -6.214736e+00 -9.113332e+00 1.859822e-15 + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + vertex -7.241153e+00 -7.998344e+00 1.791549e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.241153e+00 -7.998344e+00 1.791549e-15 + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.241153e+00 -7.998344e+00 1.791549e-15 + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + vertex -8.070051e+00 -6.729622e+00 1.713862e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -8.070051e+00 -6.729622e+00 1.713862e-15 + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + vertex -8.678817e+00 -5.341771e+00 1.628881e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.125974e+01 7.086444e+00 8.678722e-16 + vertex -1.181097e+01 7.086444e+00 8.678722e-16 + vertex -7.866329e+00 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.866329e+00 2.362057e+00 1.157158e-15 + vertex -1.181097e+01 7.086444e+00 8.678722e-16 + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.866329e+00 2.362057e+00 1.157158e-15 + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + vertex -6.943716e+00 3.636320e+00 1.079131e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -6.943716e+00 3.636320e+00 1.079131e-15 + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + vertex -5.816997e+00 4.734257e+00 1.011902e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 2.252575e+00 -1.125754e+01 1.991118e-15 + vertex 3.685961e+00 -1.076547e+01 1.960986e-15 + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex 3.685961e+00 -1.076547e+01 1.960986e-15 + vertex 5.018799e+00 -1.004417e+01 1.916820e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.567409e+00 6.678811e+00 8.928326e-16 + vertex -3.088746e+00 6.278193e+00 9.173633e-16 + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + vertex -3.088746e+00 6.278193e+00 9.173633e-16 + vertex -4.519291e+00 5.623595e+00 9.574459e-16 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + vertex -4.519291e+00 5.623595e+00 9.574459e-16 + vertex -5.816997e+00 4.734257e+00 1.011902e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -6.214736e+00 -9.113332e+00 1.859822e-15 + vertex -5.018795e+00 -1.004417e+01 1.916820e-15 + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + vertex -5.018795e+00 -1.004417e+01 1.916820e-15 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -2.598412e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.598412e+01 2.362057e+00 1.157158e-15 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -2.598412e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -3.685958e+00 -1.076547e+01 1.960986e-15 + vertex -2.252575e+00 -1.125754e+01 1.991118e-15 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -2.252575e+00 -1.125754e+01 1.991118e-15 + vertex -7.577479e-01 -1.150699e+01 2.006392e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -7.577479e-01 -1.150699e+01 2.006392e-15 + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -7.577479e-01 -1.150699e+01 2.006392e-15 + vertex 7.577479e-01 -1.150699e+01 2.006392e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex 7.577479e-01 -1.150699e+01 2.006392e-15 + vertex 2.252575e+00 -1.125754e+01 1.991118e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 5.018799e+00 -1.004417e+01 1.916820e-15 + vertex 6.214739e+00 -9.113332e+00 1.859822e-15 + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex 6.214739e+00 -9.113332e+00 1.859822e-15 + vertex 7.241153e+00 -7.998344e+00 1.791549e-15 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex 7.241153e+00 -7.998344e+00 1.791549e-15 + vertex 8.070051e+00 -6.729622e+00 1.713862e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 2.598412e+01 -2.362329e+00 5.456000e+00 + vertex 3.070851e+01 -2.362329e+00 5.456000e+00 + vertex 2.598412e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 2.598412e+01 -2.362329e+00 1.446443e-15 + vertex 3.070851e+01 -2.362329e+00 5.456000e+00 + vertex 3.070851e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.598412e+01 2.362057e+00 5.456000e+00 + vertex 2.598412e+01 -2.362329e+00 5.456000e+00 + vertex 2.598412e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.598412e+01 2.362057e+00 1.157158e-15 + vertex 2.598412e+01 -2.362329e+00 5.456000e+00 + vertex 2.598412e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 2.125974e+01 2.362057e+00 5.456000e+00 + vertex 2.598412e+01 2.362057e+00 5.456000e+00 + vertex 2.125974e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 2.125974e+01 2.362057e+00 1.157158e-15 + vertex 2.598412e+01 2.362057e+00 5.456000e+00 + vertex 2.598412e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.125974e+01 7.086444e+00 5.456000e+00 + vertex 2.125974e+01 2.362057e+00 5.456000e+00 + vertex 2.125974e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.125974e+01 7.086444e+00 8.678722e-16 + vertex 2.125974e+01 2.362057e+00 5.456000e+00 + vertex 2.125974e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 1.181097e+01 7.086444e+00 5.456000e+00 + vertex 2.125974e+01 7.086444e+00 5.456000e+00 + vertex 1.181097e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 1.181097e+01 7.086444e+00 8.678722e-16 + vertex 2.125974e+01 7.086444e+00 5.456000e+00 + vertex 2.125974e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.181097e+01 1.181110e+01 5.456000e+00 + vertex 1.181097e+01 7.086444e+00 5.456000e+00 + vertex 1.181097e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.181097e+01 1.181110e+01 5.785704e-16 + vertex 1.181097e+01 7.086444e+00 5.456000e+00 + vertex 1.181097e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 1.653535e+01 1.181110e+01 5.456000e+00 + vertex 1.181097e+01 1.181110e+01 5.456000e+00 + vertex 1.653535e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 1.653535e+01 1.181110e+01 5.785704e-16 + vertex 1.181097e+01 1.181110e+01 5.456000e+00 + vertex 1.181097e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.653535e+01 1.653549e+01 5.456000e+00 + vertex 1.653535e+01 1.181110e+01 5.456000e+00 + vertex 1.653535e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.653535e+01 1.653549e+01 2.892853e-16 + vertex 1.653535e+01 1.181110e+01 5.456000e+00 + vertex 1.653535e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 2.125974e+01 1.653549e+01 5.456000e+00 + vertex 1.653535e+01 1.653549e+01 5.456000e+00 + vertex 2.125974e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 2.125974e+01 1.653549e+01 2.892853e-16 + vertex 1.653535e+01 1.653549e+01 5.456000e+00 + vertex 1.653535e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.125974e+01 2.125987e+01 5.456000e+00 + vertex 2.125974e+01 1.653549e+01 5.456000e+00 + vertex 2.125974e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.125974e+01 2.125987e+01 0.000000e+00 + vertex 2.125974e+01 1.653549e+01 5.456000e+00 + vertex 2.125974e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 1.417316e+01 2.125987e+01 5.456000e+00 + vertex 2.125974e+01 2.125987e+01 5.456000e+00 + vertex 1.417316e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 1.417316e+01 2.125987e+01 0.000000e+00 + vertex 2.125974e+01 2.125987e+01 5.456000e+00 + vertex 2.125974e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.417316e+01 1.653549e+01 5.456000e+00 + vertex 1.417316e+01 2.125987e+01 5.456000e+00 + vertex 1.417316e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.417316e+01 1.653549e+01 2.892853e-16 + vertex 1.417316e+01 2.125987e+01 5.456000e+00 + vertex 1.417316e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 7.086580e+00 1.653549e+01 5.456000e+00 + vertex 1.417316e+01 1.653549e+01 5.456000e+00 + vertex 7.086580e+00 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 7.086580e+00 1.653549e+01 2.892853e-16 + vertex 1.417316e+01 1.653549e+01 5.456000e+00 + vertex 1.417316e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 5.456000e+00 + vertex 7.086580e+00 1.653549e+01 5.456000e+00 + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + vertex 7.086580e+00 1.653549e+01 5.456000e+00 + vertex 7.086580e+00 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -7.086578e+00 7.086444e+00 5.456000e+00 + vertex 7.086580e+00 7.086444e+00 5.456000e+00 + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + vertex 7.086580e+00 7.086444e+00 5.456000e+00 + vertex 7.086580e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -7.086578e+00 1.653549e+01 5.456000e+00 + vertex -7.086578e+00 7.086444e+00 5.456000e+00 + vertex -7.086578e+00 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -7.086578e+00 1.653549e+01 2.892853e-16 + vertex -7.086578e+00 7.086444e+00 5.456000e+00 + vertex -7.086578e+00 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -1.417316e+01 1.653549e+01 5.456000e+00 + vertex -7.086578e+00 1.653549e+01 5.456000e+00 + vertex -1.417316e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -1.417316e+01 1.653549e+01 2.892853e-16 + vertex -7.086578e+00 1.653549e+01 5.456000e+00 + vertex -7.086578e+00 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.417316e+01 2.125987e+01 5.456000e+00 + vertex -1.417316e+01 1.653549e+01 5.456000e+00 + vertex -1.417316e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.417316e+01 2.125987e+01 0.000000e+00 + vertex -1.417316e+01 1.653549e+01 5.456000e+00 + vertex -1.417316e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -2.125974e+01 2.125987e+01 5.456000e+00 + vertex -1.417316e+01 2.125987e+01 5.456000e+00 + vertex -2.125974e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -2.125974e+01 2.125987e+01 0.000000e+00 + vertex -1.417316e+01 2.125987e+01 5.456000e+00 + vertex -1.417316e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.125974e+01 1.653549e+01 5.456000e+00 + vertex -2.125974e+01 2.125987e+01 5.456000e+00 + vertex -2.125974e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.125974e+01 1.653549e+01 2.892853e-16 + vertex -2.125974e+01 2.125987e+01 5.456000e+00 + vertex -2.125974e+01 2.125987e+01 0.000000e+00 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -1.653535e+01 1.653549e+01 5.456000e+00 + vertex -2.125974e+01 1.653549e+01 5.456000e+00 + vertex -1.653535e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -1.653535e+01 1.653549e+01 2.892853e-16 + vertex -2.125974e+01 1.653549e+01 5.456000e+00 + vertex -2.125974e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.653535e+01 1.181110e+01 5.456000e+00 + vertex -1.653535e+01 1.653549e+01 5.456000e+00 + vertex -1.653535e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.653535e+01 1.181110e+01 5.785704e-16 + vertex -1.653535e+01 1.653549e+01 5.456000e+00 + vertex -1.653535e+01 1.653549e+01 2.892853e-16 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -1.181097e+01 1.181110e+01 5.456000e+00 + vertex -1.653535e+01 1.181110e+01 5.456000e+00 + vertex -1.181097e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -1.181097e+01 1.181110e+01 5.785704e-16 + vertex -1.653535e+01 1.181110e+01 5.456000e+00 + vertex -1.653535e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.181097e+01 7.086444e+00 5.456000e+00 + vertex -1.181097e+01 1.181110e+01 5.456000e+00 + vertex -1.181097e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.181097e+01 7.086444e+00 8.678722e-16 + vertex -1.181097e+01 1.181110e+01 5.456000e+00 + vertex -1.181097e+01 1.181110e+01 5.785704e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -2.125974e+01 7.086444e+00 5.456000e+00 + vertex -1.181097e+01 7.086444e+00 5.456000e+00 + vertex -2.125974e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -2.125974e+01 7.086444e+00 8.678722e-16 + vertex -1.181097e+01 7.086444e+00 5.456000e+00 + vertex -1.181097e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + vertex -2.125974e+01 7.086444e+00 5.456000e+00 + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + vertex -2.125974e+01 7.086444e+00 5.456000e+00 + vertex -2.125974e+01 7.086444e+00 8.678722e-16 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -2.598412e+01 2.362057e+00 5.456000e+00 + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + vertex -2.598412e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -2.598412e+01 2.362057e+00 1.157158e-15 + vertex -2.125974e+01 2.362057e+00 5.456000e+00 + vertex -2.125974e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.598412e+01 -2.362329e+00 5.456000e+00 + vertex -2.598412e+01 2.362057e+00 5.456000e+00 + vertex -2.598412e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.598412e+01 -2.362329e+00 1.446443e-15 + vertex -2.598412e+01 2.362057e+00 5.456000e+00 + vertex -2.598412e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -3.070851e+01 -2.362329e+00 5.456000e+00 + vertex -2.598412e+01 -2.362329e+00 5.456000e+00 + vertex -3.070851e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -3.070851e+01 -2.362329e+00 1.446443e-15 + vertex -2.598412e+01 -2.362329e+00 5.456000e+00 + vertex -2.598412e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -3.070851e+01 -1.653549e+01 5.456000e+00 + vertex -3.070851e+01 -2.362329e+00 5.456000e+00 + vertex -3.070851e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -3.070851e+01 -1.653549e+01 2.314298e-15 + vertex -3.070851e+01 -2.362329e+00 5.456000e+00 + vertex -3.070851e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -2.598412e+01 -1.653549e+01 5.456000e+00 + vertex -3.070851e+01 -1.653549e+01 5.456000e+00 + vertex -2.598412e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -2.598412e+01 -1.653549e+01 2.314298e-15 + vertex -3.070851e+01 -1.653549e+01 5.456000e+00 + vertex -3.070851e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.598412e+01 -7.086715e+00 5.456000e+00 + vertex -2.598412e+01 -1.653549e+01 5.456000e+00 + vertex -2.598412e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.598412e+01 -7.086715e+00 1.735728e-15 + vertex -2.598412e+01 -1.653549e+01 5.456000e+00 + vertex -2.598412e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + vertex -2.598412e+01 -7.086715e+00 5.456000e+00 + vertex -2.125974e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -2.125974e+01 -7.086715e+00 1.735728e-15 + vertex -2.598412e+01 -7.086715e+00 5.456000e+00 + vertex -2.598412e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.125974e+01 -1.653549e+01 5.456000e+00 + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + vertex -2.125974e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.125974e+01 -1.653549e+01 2.314298e-15 + vertex -2.125974e+01 -7.086715e+00 5.456000e+00 + vertex -2.125974e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -1.653535e+01 -1.653549e+01 5.456000e+00 + vertex -2.125974e+01 -1.653549e+01 5.456000e+00 + vertex -1.653535e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -1.653535e+01 -1.653549e+01 2.314298e-15 + vertex -2.125974e+01 -1.653549e+01 5.456000e+00 + vertex -2.125974e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.653535e+01 -2.125987e+01 5.456000e+00 + vertex -1.653535e+01 -1.653549e+01 5.456000e+00 + vertex -1.653535e+01 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.653535e+01 -2.125987e+01 2.603584e-15 + vertex -1.653535e+01 -1.653549e+01 5.456000e+00 + vertex -1.653535e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -2.362193e+00 -2.125987e+01 5.456000e+00 + vertex -1.653535e+01 -2.125987e+01 5.456000e+00 + vertex -2.362193e+00 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -2.362193e+00 -2.125987e+01 2.603584e-15 + vertex -1.653535e+01 -2.125987e+01 5.456000e+00 + vertex -1.653535e+01 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.362193e+00 -1.653549e+01 5.456000e+00 + vertex -2.362193e+00 -2.125987e+01 5.456000e+00 + vertex -2.362193e+00 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -2.362193e+00 -1.653549e+01 2.314298e-15 + vertex -2.362193e+00 -2.125987e+01 5.456000e+00 + vertex -2.362193e+00 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + vertex -2.362193e+00 -1.653549e+01 5.456000e+00 + vertex -1.181097e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -1.181097e+01 -1.653549e+01 2.314298e-15 + vertex -2.362193e+00 -1.653549e+01 5.456000e+00 + vertex -2.362193e+00 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.181097e+01 -1.181110e+01 5.456000e+00 + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -1.181097e+01 -1.653549e+01 5.456000e+00 + vertex -1.181097e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + vertex -1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + vertex -1.181097e+01 -1.181110e+01 5.456000e+00 + vertex -1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.181097e+01 -1.653549e+01 5.456000e+00 + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 1.181097e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.181097e+01 -1.653549e+01 2.314298e-15 + vertex 1.181097e+01 -1.181110e+01 5.456000e+00 + vertex 1.181097e+01 -1.181110e+01 2.025013e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 2.362195e+00 -1.653549e+01 5.456000e+00 + vertex 1.181097e+01 -1.653549e+01 5.456000e+00 + vertex 2.362195e+00 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 2.362195e+00 -1.653549e+01 2.314298e-15 + vertex 1.181097e+01 -1.653549e+01 5.456000e+00 + vertex 1.181097e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.362195e+00 -2.125987e+01 5.456000e+00 + vertex 2.362195e+00 -1.653549e+01 5.456000e+00 + vertex 2.362195e+00 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.362195e+00 -2.125987e+01 2.603584e-15 + vertex 2.362195e+00 -1.653549e+01 5.456000e+00 + vertex 2.362195e+00 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 1.653535e+01 -2.125987e+01 5.456000e+00 + vertex 2.362195e+00 -2.125987e+01 5.456000e+00 + vertex 1.653535e+01 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 1.653535e+01 -2.125987e+01 2.603584e-15 + vertex 2.362195e+00 -2.125987e+01 5.456000e+00 + vertex 2.362195e+00 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.653535e+01 -1.653549e+01 5.456000e+00 + vertex 1.653535e+01 -2.125987e+01 5.456000e+00 + vertex 1.653535e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.653535e+01 -1.653549e+01 2.314298e-15 + vertex 1.653535e+01 -2.125987e+01 5.456000e+00 + vertex 1.653535e+01 -2.125987e+01 2.603584e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 2.125974e+01 -1.653549e+01 5.456000e+00 + vertex 1.653535e+01 -1.653549e+01 5.456000e+00 + vertex 2.125974e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 2.125974e+01 -1.653549e+01 2.314298e-15 + vertex 1.653535e+01 -1.653549e+01 5.456000e+00 + vertex 1.653535e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + vertex 2.125974e+01 -1.653549e+01 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + vertex 2.125974e+01 -1.653549e+01 5.456000e+00 + vertex 2.125974e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 2.598412e+01 -7.086715e+00 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + vertex 2.598412e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 2.598412e+01 -7.086715e+00 1.735728e-15 + vertex 2.125974e+01 -7.086715e+00 5.456000e+00 + vertex 2.125974e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.598412e+01 -1.653549e+01 5.456000e+00 + vertex 2.598412e+01 -7.086715e+00 5.456000e+00 + vertex 2.598412e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 2.598412e+01 -1.653549e+01 2.314298e-15 + vertex 2.598412e+01 -7.086715e+00 5.456000e+00 + vertex 2.598412e+01 -7.086715e+00 1.735728e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 3.070851e+01 -1.653549e+01 5.456000e+00 + vertex 2.598412e+01 -1.653549e+01 5.456000e+00 + vertex 3.070851e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 3.070851e+01 -1.653549e+01 2.314298e-15 + vertex 2.598412e+01 -1.653549e+01 5.456000e+00 + vertex 2.598412e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 3.070851e+01 -2.362329e+00 5.456000e+00 + vertex 3.070851e+01 -1.653549e+01 5.456000e+00 + vertex 3.070851e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 3.070851e+01 -2.362329e+00 1.446443e-15 + vertex 3.070851e+01 -1.653549e+01 5.456000e+00 + vertex 3.070851e+01 -1.653549e+01 2.314298e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -7.086578e+00 2.362057e+00 3.472000e+00 + vertex -7.086578e+00 2.362057e+00 5.456000e+00 + vertex -7.866329e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -7.866329e+00 2.362057e+00 3.472000e+00 + vertex -7.086578e+00 2.362057e+00 5.456000e+00 + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -7.866329e+00 2.362057e+00 3.472000e+00 + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + vertex -7.866329e+00 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex -7.866329e+00 2.362057e+00 1.157158e-15 + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + vertex -1.181097e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.181097e+01 2.362057e+00 5.456000e+00 + vertex -1.181097e+01 -2.362329e+00 5.456000e+00 + vertex -1.181097e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex -1.181097e+01 2.362057e+00 1.157158e-15 + vertex -1.181097e+01 -2.362329e+00 5.456000e+00 + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -9.176000e+00 -2.362329e+00 1.446443e-15 + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + vertex -9.176000e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -9.176000e+00 -2.362329e+00 3.472000e+00 + vertex -1.181097e+01 -2.362329e+00 1.446443e-15 + vertex -1.181097e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -9.176000e+00 -2.362329e+00 3.472000e+00 + vertex -1.181097e+01 -2.362329e+00 5.456000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + vertex -1.181097e+01 -2.362329e+00 5.456000e+00 + vertex -7.086578e+00 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.181097e+01 -2.362329e+00 5.456000e+00 + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal -1.000000e+00 0.000000e+00 0.000000e+00 + outer loop + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + vertex 1.181097e+01 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 7.866333e+00 2.362057e+00 1.157158e-15 + vertex 1.181097e+01 2.362057e+00 1.157158e-15 + vertex 7.866333e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 7.866333e+00 2.362057e+00 3.472000e+00 + vertex 1.181097e+01 2.362057e+00 1.157158e-15 + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 7.866333e+00 2.362057e+00 3.472000e+00 + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + vertex 7.086580e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -1.000000e+00 6.123234e-17 + outer loop + vertex 7.086580e+00 2.362057e+00 3.472000e+00 + vertex 1.181097e+01 2.362057e+00 5.456000e+00 + vertex 7.086580e+00 2.362057e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + vertex 7.086580e+00 -2.362329e+00 5.456000e+00 + vertex 9.176000e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 9.176000e+00 -2.362329e+00 3.472000e+00 + vertex 7.086580e+00 -2.362329e+00 5.456000e+00 + vertex 1.181097e+01 -2.362329e+00 5.456000e+00 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 9.176000e+00 -2.362329e+00 3.472000e+00 + vertex 1.181097e+01 -2.362329e+00 5.456000e+00 + vertex 9.176000e+00 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 0.000000e+00 1.000000e+00 -6.123234e-17 + outer loop + vertex 9.176000e+00 -2.362329e+00 1.446443e-15 + vertex 1.181097e+01 -2.362329e+00 5.456000e+00 + vertex 1.181097e+01 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 8.264604e-01 -5.629948e-01 3.447349e-17 + outer loop + vertex -7.866329e+00 2.362057e+00 3.472000e+00 + vertex -7.866329e+00 2.362057e+00 1.157158e-15 + vertex -6.943716e+00 3.636320e+00 1.079131e-15 + endloop + endfacet + facet normal 7.928349e-01 -6.094364e-01 3.731721e-17 + outer loop + vertex -7.866329e+00 2.362057e+00 3.472000e+00 + vertex -6.943716e+00 3.636320e+00 1.079131e-15 + vertex -6.943716e+00 3.636320e+00 3.472000e+00 + endloop + endfacet + facet normal 7.181453e-01 -6.958932e-01 4.261117e-17 + outer loop + vertex -6.943716e+00 3.636320e+00 3.472000e+00 + vertex -6.943716e+00 3.636320e+00 1.079131e-15 + vertex -5.816997e+00 4.734257e+00 1.011902e-15 + endloop + endfacet + facet normal 6.770810e-01 -7.359086e-01 4.506141e-17 + outer loop + vertex -6.943716e+00 3.636320e+00 3.472000e+00 + vertex -5.816997e+00 4.734257e+00 1.011902e-15 + vertex -5.816997e+00 4.734257e+00 3.472000e+00 + endloop + endfacet + facet normal 5.887207e-01 -8.083366e-01 4.949634e-17 + outer loop + vertex -5.816997e+00 4.734257e+00 3.472000e+00 + vertex -5.816997e+00 4.734257e+00 1.011902e-15 + vertex -4.519291e+00 5.623595e+00 9.574459e-16 + endloop + endfacet + facet normal 5.414247e-01 -8.407493e-01 5.148104e-17 + outer loop + vertex -5.816997e+00 4.734257e+00 3.472000e+00 + vertex -4.519291e+00 5.623595e+00 9.574459e-16 + vertex -4.519291e+00 5.623595e+00 3.472000e+00 + endloop + endfacet + facet normal 4.419912e-01 -8.970194e-01 5.492660e-17 + outer loop + vertex -4.519291e+00 5.623595e+00 3.472000e+00 + vertex -4.519291e+00 5.623595e+00 9.574459e-16 + vertex -3.088746e+00 6.278193e+00 9.173633e-16 + endloop + endfacet + facet normal 3.898538e-01 -9.208769e-01 5.638744e-17 + outer loop + vertex -4.519291e+00 5.623595e+00 3.472000e+00 + vertex -3.088746e+00 6.278193e+00 9.173633e-16 + vertex -3.088746e+00 6.278193e+00 3.472000e+00 + endloop + endfacet + facet normal 2.822698e-01 -9.593350e-01 5.874233e-17 + outer loop + vertex -3.088746e+00 6.278193e+00 3.472000e+00 + vertex -3.088746e+00 6.278193e+00 9.173633e-16 + vertex -1.567409e+00 6.678811e+00 8.928326e-16 + endloop + endfacet + facet normal 2.268233e-01 -9.739359e-01 5.963637e-17 + outer loop + vertex -3.088746e+00 6.278193e+00 3.472000e+00 + vertex -1.567409e+00 6.678811e+00 8.928326e-16 + vertex -1.567409e+00 6.678811e+00 3.472000e+00 + endloop + endfacet + facet normal 1.142512e-01 -9.934519e-01 6.083139e-17 + outer loop + vertex -1.567409e+00 6.678811e+00 3.472000e+00 + vertex -1.567409e+00 6.678811e+00 8.928326e-16 + vertex 0.000000e+00 6.813671e+00 8.845748e-16 + endloop + endfacet + facet normal 5.712563e-02 -9.983670e-01 6.113235e-17 + outer loop + vertex -1.567409e+00 6.678811e+00 3.472000e+00 + vertex 0.000000e+00 6.813671e+00 8.845748e-16 + vertex 0.000000e+00 6.813671e+00 3.472000e+00 + endloop + endfacet + facet normal -5.712563e-02 -9.983670e-01 6.113235e-17 + outer loop + vertex 0.000000e+00 6.813671e+00 3.472000e+00 + vertex 0.000000e+00 6.813671e+00 8.845748e-16 + vertex 1.567411e+00 6.678811e+00 8.928326e-16 + endloop + endfacet + facet normal -1.142512e-01 -9.934519e-01 6.083139e-17 + outer loop + vertex 0.000000e+00 6.813671e+00 3.472000e+00 + vertex 1.567411e+00 6.678811e+00 8.928326e-16 + vertex 1.567411e+00 6.678811e+00 3.472000e+00 + endloop + endfacet + facet normal -2.268233e-01 -9.739359e-01 5.963637e-17 + outer loop + vertex 1.567411e+00 6.678811e+00 3.472000e+00 + vertex 1.567411e+00 6.678811e+00 8.928326e-16 + vertex 3.088746e+00 6.278193e+00 9.173633e-16 + endloop + endfacet + facet normal -2.822698e-01 -9.593350e-01 5.874233e-17 + outer loop + vertex 1.567411e+00 6.678811e+00 3.472000e+00 + vertex 3.088746e+00 6.278193e+00 9.173633e-16 + vertex 3.088746e+00 6.278193e+00 3.472000e+00 + endloop + endfacet + facet normal -3.898537e-01 -9.208769e-01 5.638744e-17 + outer loop + vertex 3.088746e+00 6.278193e+00 3.472000e+00 + vertex 3.088746e+00 6.278193e+00 9.173633e-16 + vertex 4.519291e+00 5.623595e+00 9.574459e-16 + endloop + endfacet + facet normal -4.419912e-01 -8.970194e-01 5.492660e-17 + outer loop + vertex 3.088746e+00 6.278193e+00 3.472000e+00 + vertex 4.519291e+00 5.623595e+00 9.574459e-16 + vertex 4.519291e+00 5.623595e+00 3.472000e+00 + endloop + endfacet + facet normal -5.414248e-01 -8.407493e-01 5.148104e-17 + outer loop + vertex 4.519291e+00 5.623595e+00 3.472000e+00 + vertex 4.519291e+00 5.623595e+00 9.574459e-16 + vertex 5.816999e+00 4.734257e+00 1.011902e-15 + endloop + endfacet + facet normal -5.887207e-01 -8.083366e-01 4.949634e-17 + outer loop + vertex 4.519291e+00 5.623595e+00 3.472000e+00 + vertex 5.816999e+00 4.734257e+00 1.011902e-15 + vertex 5.816999e+00 4.734257e+00 3.472000e+00 + endloop + endfacet + facet normal -6.770810e-01 -7.359086e-01 4.506141e-17 + outer loop + vertex 5.816999e+00 4.734257e+00 3.472000e+00 + vertex 5.816999e+00 4.734257e+00 1.011902e-15 + vertex 6.943716e+00 3.636320e+00 1.079131e-15 + endloop + endfacet + facet normal -7.181453e-01 -6.958932e-01 4.261117e-17 + outer loop + vertex 5.816999e+00 4.734257e+00 3.472000e+00 + vertex 6.943716e+00 3.636320e+00 1.079131e-15 + vertex 6.943716e+00 3.636320e+00 3.472000e+00 + endloop + endfacet + facet normal -7.928349e-01 -6.094364e-01 3.731721e-17 + outer loop + vertex 6.943716e+00 3.636320e+00 3.472000e+00 + vertex 6.943716e+00 3.636320e+00 1.079131e-15 + vertex 7.866333e+00 2.362057e+00 1.157158e-15 + endloop + endfacet + facet normal -8.264605e-01 -5.629948e-01 3.447349e-17 + outer loop + vertex 6.943716e+00 3.636320e+00 3.472000e+00 + vertex 7.866333e+00 2.362057e+00 1.157158e-15 + vertex 7.866333e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal -9.984846e-01 5.503191e-02 -3.369733e-18 + outer loop + vertex 9.176000e+00 -2.362329e+00 3.472000e+00 + vertex 9.176000e+00 -2.362329e+00 1.446443e-15 + vertex 9.050850e+00 -3.872648e+00 1.538923e-15 + endloop + endfacet + facet normal -9.939246e-01 1.100638e-01 -6.739466e-18 + outer loop + vertex 9.176000e+00 -2.362329e+00 3.472000e+00 + vertex 9.050850e+00 -3.872648e+00 1.538923e-15 + vertex 9.050850e+00 -3.872648e+00 3.472000e+00 + endloop + endfacet + facet normal -9.758086e-01 2.186265e-01 -1.338701e-17 + outer loop + vertex 9.050850e+00 -3.872648e+00 3.472000e+00 + vertex 9.050850e+00 -3.872648e+00 1.538923e-15 + vertex 8.678819e+00 -5.341771e+00 1.628881e-15 + endloop + endfacet + facet normal -9.622528e-01 2.721573e-01 -1.666483e-17 + outer loop + vertex 9.050850e+00 -3.872648e+00 3.472000e+00 + vertex 8.678819e+00 -5.341771e+00 1.628881e-15 + vertex 8.678819e+00 -5.341771e+00 3.472000e+00 + endloop + endfacet + facet normal -9.265151e-01 3.762575e-01 -2.303913e-17 + outer loop + vertex 8.678819e+00 -5.341771e+00 3.472000e+00 + vertex 8.678819e+00 -5.341771e+00 1.628881e-15 + vertex 8.070051e+00 -6.729622e+00 1.713862e-15 + endloop + endfacet + facet normal -9.043332e-01 4.268270e-01 -2.613562e-17 + outer loop + vertex 8.678819e+00 -5.341771e+00 3.472000e+00 + vertex 8.070051e+00 -6.729622e+00 1.713862e-15 + vertex 8.070051e+00 -6.729622e+00 3.472000e+00 + endloop + endfacet + facet normal -8.519487e-01 5.236253e-01 -3.206280e-17 + outer loop + vertex 8.070051e+00 -6.729622e+00 3.472000e+00 + vertex 8.070051e+00 -6.729622e+00 1.713862e-15 + vertex 7.241153e+00 -7.998344e+00 1.791549e-15 + endloop + endfacet + facet normal -8.217459e-01 5.698540e-01 -3.489350e-17 + outer loop + vertex 8.070051e+00 -6.729622e+00 3.472000e+00 + vertex 7.241153e+00 -7.998344e+00 1.791549e-15 + vertex 7.241153e+00 -7.998344e+00 3.472000e+00 + endloop + endfacet + facet normal -7.541434e-01 6.567098e-01 -4.021188e-17 + outer loop + vertex 7.241153e+00 -7.998344e+00 3.472000e+00 + vertex 7.241153e+00 -7.998344e+00 1.791549e-15 + vertex 6.214739e+00 -9.113332e+00 1.859822e-15 + endloop + endfacet + facet normal -7.167435e-01 6.973369e-01 -4.269957e-17 + outer loop + vertex 7.241153e+00 -7.998344e+00 3.472000e+00 + vertex 6.214739e+00 -9.113332e+00 1.859822e-15 + vertex 6.214739e+00 -9.113332e+00 3.472000e+00 + endloop + endfacet + facet normal -6.357669e-01 7.718811e-01 -4.726408e-17 + outer loop + vertex 6.214739e+00 -9.113332e+00 3.472000e+00 + vertex 6.214739e+00 -9.113332e+00 1.859822e-15 + vertex 5.018799e+00 -1.004417e+01 1.916820e-15 + endloop + endfacet + facet normal -5.921901e-01 8.057982e-01 -4.934091e-17 + outer loop + vertex 6.214739e+00 -9.113332e+00 3.472000e+00 + vertex 5.018799e+00 -1.004417e+01 1.916820e-15 + vertex 5.018799e+00 -1.004417e+01 3.472000e+00 + endloop + endfacet + facet normal -5.000484e-01 8.659974e-01 -5.302705e-17 + outer loop + vertex 5.018799e+00 -1.004417e+01 3.472000e+00 + vertex 5.018799e+00 -1.004417e+01 1.916820e-15 + vertex 3.685961e+00 -1.076547e+01 1.960986e-15 + endloop + endfacet + facet normal -4.514834e-01 8.922795e-01 -5.463636e-17 + outer loop + vertex 5.018799e+00 -1.004417e+01 3.472000e+00 + vertex 3.685961e+00 -1.076547e+01 1.960986e-15 + vertex 3.685961e+00 -1.076547e+01 3.472000e+00 + endloop + endfacet + facet normal -3.506899e-01 9.364916e-01 -5.734357e-17 + outer loop + vertex 3.685961e+00 -1.076547e+01 3.472000e+00 + vertex 3.685961e+00 -1.076547e+01 1.960986e-15 + vertex 2.252575e+00 -1.125754e+01 1.991118e-15 + endloop + endfacet + facet normal -2.984614e-01 9.544217e-01 -5.844147e-17 + outer loop + vertex 3.685961e+00 -1.076547e+01 3.472000e+00 + vertex 2.252575e+00 -1.125754e+01 1.991118e-15 + vertex 2.252575e+00 -1.125754e+01 3.472000e+00 + endloop + endfacet + facet normal -1.917655e-01 9.814408e-01 -6.009592e-17 + outer loop + vertex 2.252575e+00 -1.125754e+01 3.472000e+00 + vertex 2.252575e+00 -1.125754e+01 1.991118e-15 + vertex 7.577479e-01 -1.150699e+01 2.006392e-15 + endloop + endfacet + facet normal -1.372982e-01 9.905298e-01 -6.065246e-17 + outer loop + vertex 2.252575e+00 -1.125754e+01 3.472000e+00 + vertex 7.577479e-01 -1.150699e+01 2.006392e-15 + vertex 7.577479e-01 -1.150699e+01 3.472000e+00 + endloop + endfacet + facet normal -2.761026e-02 9.996187e-01 -6.120900e-17 + outer loop + vertex 7.577479e-01 -1.150699e+01 3.472000e+00 + vertex 7.577479e-01 -1.150699e+01 2.006392e-15 + vertex -7.577479e-01 -1.150699e+01 2.006392e-15 + endloop + endfacet + facet normal 2.761026e-02 9.996187e-01 -6.120900e-17 + outer loop + vertex 7.577479e-01 -1.150699e+01 3.472000e+00 + vertex -7.577479e-01 -1.150699e+01 2.006392e-15 + vertex -7.577479e-01 -1.150699e+01 3.472000e+00 + endloop + endfacet + facet normal 1.372982e-01 9.905298e-01 -6.065246e-17 + outer loop + vertex -7.577479e-01 -1.150699e+01 3.472000e+00 + vertex -7.577479e-01 -1.150699e+01 2.006392e-15 + vertex -2.252575e+00 -1.125754e+01 1.991118e-15 + endloop + endfacet + facet normal 1.917655e-01 9.814408e-01 -6.009592e-17 + outer loop + vertex -7.577479e-01 -1.150699e+01 3.472000e+00 + vertex -2.252575e+00 -1.125754e+01 1.991118e-15 + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + endloop + endfacet + facet normal 2.984614e-01 9.544217e-01 -5.844147e-17 + outer loop + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + vertex -2.252575e+00 -1.125754e+01 1.991118e-15 + vertex -3.685958e+00 -1.076547e+01 1.960986e-15 + endloop + endfacet + facet normal 3.506899e-01 9.364916e-01 -5.734357e-17 + outer loop + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + vertex -3.685958e+00 -1.076547e+01 1.960986e-15 + vertex -3.685958e+00 -1.076547e+01 3.472000e+00 + endloop + endfacet + facet normal 4.514834e-01 8.922795e-01 -5.463636e-17 + outer loop + vertex -3.685958e+00 -1.076547e+01 3.472000e+00 + vertex -3.685958e+00 -1.076547e+01 1.960986e-15 + vertex -5.018795e+00 -1.004417e+01 1.916820e-15 + endloop + endfacet + facet normal 5.000484e-01 8.659974e-01 -5.302705e-17 + outer loop + vertex -3.685958e+00 -1.076547e+01 3.472000e+00 + vertex -5.018795e+00 -1.004417e+01 1.916820e-15 + vertex -5.018795e+00 -1.004417e+01 3.472000e+00 + endloop + endfacet + facet normal 5.921901e-01 8.057982e-01 -4.934091e-17 + outer loop + vertex -5.018795e+00 -1.004417e+01 3.472000e+00 + vertex -5.018795e+00 -1.004417e+01 1.916820e-15 + vertex -6.214736e+00 -9.113332e+00 1.859822e-15 + endloop + endfacet + facet normal 6.357669e-01 7.718811e-01 -4.726408e-17 + outer loop + vertex -5.018795e+00 -1.004417e+01 3.472000e+00 + vertex -6.214736e+00 -9.113332e+00 1.859822e-15 + vertex -6.214736e+00 -9.113332e+00 3.472000e+00 + endloop + endfacet + facet normal 7.167435e-01 6.973369e-01 -4.269957e-17 + outer loop + vertex -6.214736e+00 -9.113332e+00 3.472000e+00 + vertex -6.214736e+00 -9.113332e+00 1.859822e-15 + vertex -7.241153e+00 -7.998344e+00 1.791549e-15 + endloop + endfacet + facet normal 7.541434e-01 6.567098e-01 -4.021188e-17 + outer loop + vertex -6.214736e+00 -9.113332e+00 3.472000e+00 + vertex -7.241153e+00 -7.998344e+00 1.791549e-15 + vertex -7.241153e+00 -7.998344e+00 3.472000e+00 + endloop + endfacet + facet normal 8.217460e-01 5.698540e-01 -3.489349e-17 + outer loop + vertex -7.241153e+00 -7.998344e+00 3.472000e+00 + vertex -7.241153e+00 -7.998344e+00 1.791549e-15 + vertex -8.070051e+00 -6.729622e+00 1.713862e-15 + endloop + endfacet + facet normal 8.519487e-01 5.236253e-01 -3.206280e-17 + outer loop + vertex -7.241153e+00 -7.998344e+00 3.472000e+00 + vertex -8.070051e+00 -6.729622e+00 1.713862e-15 + vertex -8.070051e+00 -6.729622e+00 3.472000e+00 + endloop + endfacet + facet normal 9.043332e-01 4.268270e-01 -2.613562e-17 + outer loop + vertex -8.070051e+00 -6.729622e+00 3.472000e+00 + vertex -8.070051e+00 -6.729622e+00 1.713862e-15 + vertex -8.678817e+00 -5.341771e+00 1.628881e-15 + endloop + endfacet + facet normal 9.265151e-01 3.762575e-01 -2.303913e-17 + outer loop + vertex -8.070051e+00 -6.729622e+00 3.472000e+00 + vertex -8.678817e+00 -5.341771e+00 1.628881e-15 + vertex -8.678817e+00 -5.341771e+00 3.472000e+00 + endloop + endfacet + facet normal 9.622528e-01 2.721573e-01 -1.666483e-17 + outer loop + vertex -8.678817e+00 -5.341771e+00 3.472000e+00 + vertex -8.678817e+00 -5.341771e+00 1.628881e-15 + vertex -9.050850e+00 -3.872648e+00 1.538923e-15 + endloop + endfacet + facet normal 9.758086e-01 2.186265e-01 -1.338701e-17 + outer loop + vertex -8.678817e+00 -5.341771e+00 3.472000e+00 + vertex -9.050850e+00 -3.872648e+00 1.538923e-15 + vertex -9.050850e+00 -3.872648e+00 3.472000e+00 + endloop + endfacet + facet normal 9.939246e-01 1.100638e-01 -6.739466e-18 + outer loop + vertex -9.050850e+00 -3.872648e+00 3.472000e+00 + vertex -9.050850e+00 -3.872648e+00 1.538923e-15 + vertex -9.176000e+00 -2.362329e+00 1.446443e-15 + endloop + endfacet + facet normal 9.984846e-01 5.503191e-02 -3.369733e-18 + outer loop + vertex -9.050850e+00 -3.872648e+00 3.472000e+00 + vertex -9.176000e+00 -2.362329e+00 1.446443e-15 + vertex -9.176000e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 6.943716e+00 3.636320e+00 3.472000e+00 + vertex 7.866333e+00 2.362057e+00 3.472000e+00 + vertex 7.086580e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -9.050850e+00 -3.872648e+00 3.472000e+00 + vertex -9.176000e+00 -2.362329e+00 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 5.816999e+00 4.734257e+00 3.472000e+00 + vertex 6.943716e+00 3.636320e+00 3.472000e+00 + vertex 4.519291e+00 5.623595e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 4.519291e+00 5.623595e+00 3.472000e+00 + vertex 6.943716e+00 3.636320e+00 3.472000e+00 + vertex 7.086580e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 4.519291e+00 5.623595e+00 3.472000e+00 + vertex 7.086580e+00 2.362057e+00 3.472000e+00 + vertex 3.088746e+00 6.278193e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 3.088746e+00 6.278193e+00 3.472000e+00 + vertex 7.086580e+00 2.362057e+00 3.472000e+00 + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 9.176000e+00 -2.362329e+00 3.472000e+00 + vertex 9.050850e+00 -3.872648e+00 3.472000e+00 + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + vertex 9.050850e+00 -3.872648e+00 3.472000e+00 + vertex 8.678819e+00 -5.341771e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + vertex -3.685958e+00 -1.076547e+01 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + vertex -3.685958e+00 -1.076547e+01 3.472000e+00 + vertex -5.018795e+00 -1.004417e+01 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + vertex -5.018795e+00 -1.004417e+01 3.472000e+00 + vertex -6.214736e+00 -9.113332e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.866329e+00 2.362057e+00 3.472000e+00 + vertex -6.943716e+00 3.636320e+00 3.472000e+00 + vertex -7.086578e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.086578e+00 2.362057e+00 3.472000e+00 + vertex -6.943716e+00 3.636320e+00 3.472000e+00 + vertex -5.816997e+00 4.734257e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -8.678817e+00 -5.341771e+00 3.472000e+00 + vertex -9.050850e+00 -3.872648e+00 3.472000e+00 + vertex -8.070051e+00 -6.729622e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -8.070051e+00 -6.729622e+00 3.472000e+00 + vertex -9.050850e+00 -3.872648e+00 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -8.070051e+00 -6.729622e+00 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + vertex -7.241153e+00 -7.998344e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.241153e+00 -7.998344e+00 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + vertex -6.214736e+00 -9.113332e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.567411e+00 6.678811e+00 3.472000e+00 + vertex 3.088746e+00 6.278193e+00 3.472000e+00 + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + vertex 3.088746e+00 6.278193e+00 3.472000e+00 + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + vertex -7.577479e-01 -1.150699e+01 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.577479e-01 -1.150699e+01 3.472000e+00 + vertex 7.086580e+00 -2.362329e+00 3.472000e+00 + vertex 8.678819e+00 -5.341771e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -7.577479e-01 -1.150699e+01 3.472000e+00 + vertex 8.678819e+00 -5.341771e+00 3.472000e+00 + vertex 7.577479e-01 -1.150699e+01 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.577479e-01 -1.150699e+01 3.472000e+00 + vertex 8.678819e+00 -5.341771e+00 3.472000e+00 + vertex 8.070051e+00 -6.729622e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 7.577479e-01 -1.150699e+01 3.472000e+00 + vertex 8.070051e+00 -6.729622e+00 3.472000e+00 + vertex 2.252575e+00 -1.125754e+01 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 2.252575e+00 -1.125754e+01 3.472000e+00 + vertex 8.070051e+00 -6.729622e+00 3.472000e+00 + vertex 7.241153e+00 -7.998344e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 2.252575e+00 -1.125754e+01 3.472000e+00 + vertex 7.241153e+00 -7.998344e+00 3.472000e+00 + vertex 3.685961e+00 -1.076547e+01 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 3.685961e+00 -1.076547e+01 3.472000e+00 + vertex 7.241153e+00 -7.998344e+00 3.472000e+00 + vertex 6.214739e+00 -9.113332e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 3.685961e+00 -1.076547e+01 3.472000e+00 + vertex 6.214739e+00 -9.113332e+00 3.472000e+00 + vertex 5.018799e+00 -1.004417e+01 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 1.567411e+00 6.678811e+00 3.472000e+00 + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + vertex 0.000000e+00 6.813671e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 0.000000e+00 6.813671e+00 3.472000e+00 + vertex -2.252575e+00 -1.125754e+01 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex 0.000000e+00 6.813671e+00 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + vertex -1.567409e+00 6.678811e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.567409e+00 6.678811e+00 3.472000e+00 + vertex -7.086578e+00 -2.362329e+00 3.472000e+00 + vertex -7.086578e+00 2.362057e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -1.567409e+00 6.678811e+00 3.472000e+00 + vertex -7.086578e+00 2.362057e+00 3.472000e+00 + vertex -3.088746e+00 6.278193e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -3.088746e+00 6.278193e+00 3.472000e+00 + vertex -7.086578e+00 2.362057e+00 3.472000e+00 + vertex -5.816997e+00 4.734257e+00 3.472000e+00 + endloop + endfacet + facet normal 0.000000e+00 -6.123234e-17 -1.000000e+00 + outer loop + vertex -3.088746e+00 6.278193e+00 3.472000e+00 + vertex -5.816997e+00 4.734257e+00 3.472000e+00 + vertex -4.519291e+00 5.623595e+00 3.472000e+00 + endloop + endfacet +endsolid Default diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/basic_LwjglBasicExample.jpg b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/basic_LwjglBasicExample.jpg Binary files differdeleted file mode 100644 index 6964a8d..0000000 --- a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/basic_LwjglBasicExample.jpg +++ /dev/null diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/basic_LwjglHeadlessExample.jpg b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/basic_LwjglHeadlessExample.jpg Binary files differdeleted file mode 100644 index 88d2a31..0000000 --- a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/basic_LwjglHeadlessExample.jpg +++ /dev/null diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/canvas_LwjglAwtExample.jpg b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/canvas_LwjglAwtExample.jpg Binary files differdeleted file mode 100644 index ae5cc0d..0000000 --- a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/canvas_LwjglAwtExample.jpg +++ /dev/null diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/canvas_LwjglSwtExample.jpg b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/canvas_LwjglSwtExample.jpg Binary files differdeleted file mode 100644 index ae5cc0d..0000000 --- a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/canvas_LwjglSwtExample.jpg +++ /dev/null diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/pipeline_SimplePlyExample.jpg b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/pipeline_SimplePlyExample.jpg Binary files differnew file mode 100644 index 0000000..2084f5c --- /dev/null +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/pipeline_SimplePlyExample.jpg diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/pipeline_SimpleStlExample.jpg b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/pipeline_SimpleStlExample.jpg Binary files differnew file mode 100644 index 0000000..ca02848 --- /dev/null +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/pipeline_SimpleStlExample.jpg diff --git a/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/terrain_MountainShadowTerrainExample.jpg b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/terrain_MountainShadowTerrainExample.jpg Binary files differnew file mode 100644 index 0000000..57bcc7c --- /dev/null +++ b/ardor3d-examples/src/main/resources/com/ardor3d/example/media/thumbnails/terrain_MountainShadowTerrainExample.jpg |